blob: 5193c150375c31eac12ebc35a046e0920898126c [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"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200105
106 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
107 self.assertEqual(len(data), 16)
108 self.assertEqual(is_cryptographic, v == 1)
109 if v:
110 data = ssl.RAND_bytes(16)
111 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200112 else:
113 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200114
Thomas Woutersed03b412007-08-28 21:37:11 +0000115 try:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000116 ssl.RAND_egd(1)
117 except TypeError:
118 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000119 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000120 print("didn't raise TypeError")
121 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000122
Antoine Pitrou480a1242010-04-28 21:37:09 +0000123 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000124 # note that this uses an 'unofficial' function in _ssl.c,
125 # provided solely for this test, to exercise the certificate
126 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000127 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000128 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000129 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Thomas Woutersed03b412007-08-28 21:37:11 +0000130
Antoine Pitrou480a1242010-04-28 21:37:09 +0000131 def test_DER_to_PEM(self):
132 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
133 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000134 d1 = ssl.PEM_cert_to_DER_cert(pem)
135 p2 = ssl.DER_cert_to_PEM_cert(d1)
136 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000137 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000138 if not p2.startswith(ssl.PEM_HEADER + '\n'):
139 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
140 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
141 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000142
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000143 def test_openssl_version(self):
144 n = ssl.OPENSSL_VERSION_NUMBER
145 t = ssl.OPENSSL_VERSION_INFO
146 s = ssl.OPENSSL_VERSION
147 self.assertIsInstance(n, int)
148 self.assertIsInstance(t, tuple)
149 self.assertIsInstance(s, str)
150 # Some sanity checks follow
151 # >= 0.9
152 self.assertGreaterEqual(n, 0x900000)
153 # < 2.0
154 self.assertLess(n, 0x20000000)
155 major, minor, fix, patch, status = t
156 self.assertGreaterEqual(major, 0)
157 self.assertLess(major, 2)
158 self.assertGreaterEqual(minor, 0)
159 self.assertLess(minor, 256)
160 self.assertGreaterEqual(fix, 0)
161 self.assertLess(fix, 256)
162 self.assertGreaterEqual(patch, 0)
163 self.assertLessEqual(patch, 26)
164 self.assertGreaterEqual(status, 0)
165 self.assertLessEqual(status, 15)
166 # Version string as returned by OpenSSL, the format might change
167 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
168 (s, t))
169
Antoine Pitrou9d543662010-04-23 23:10:32 +0000170 @support.cpython_only
171 def test_refcycle(self):
172 # Issue #7943: an SSL object doesn't create reference cycles with
173 # itself.
174 s = socket.socket(socket.AF_INET)
175 ss = ssl.wrap_socket(s)
176 wr = weakref.ref(ss)
177 del ss
178 self.assertEqual(wr(), None)
179
Antoine Pitroua468adc2010-09-14 14:43:44 +0000180 def test_wrapped_unconnected(self):
181 # Methods on an unconnected SSLSocket propagate the original
182 # socket.error raise by the underlying socket object.
183 s = socket.socket(socket.AF_INET)
184 ss = ssl.wrap_socket(s)
185 self.assertRaises(socket.error, ss.recv, 1)
186 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
187 self.assertRaises(socket.error, ss.recvfrom, 1)
188 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
189 self.assertRaises(socket.error, ss.send, b'x')
190 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
191
Antoine Pitrou40f08742010-04-24 22:04:40 +0000192 def test_timeout(self):
193 # Issue #8524: when creating an SSL socket, the timeout of the
194 # original socket should be retained.
195 for timeout in (None, 0.0, 5.0):
196 s = socket.socket(socket.AF_INET)
197 s.settimeout(timeout)
198 ss = ssl.wrap_socket(s)
199 self.assertEqual(timeout, ss.gettimeout())
200
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000201 def test_errors(self):
202 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000203 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000204 "certfile must be specified",
205 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000206 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000207 "certfile must be specified for server-side operations",
208 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000209 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000210 "certfile must be specified for server-side operations",
211 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000212 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000213 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000214 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000215 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000216 with socket.socket() as sock:
217 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000218 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000219 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000220 with socket.socket() as sock:
221 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000222 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000223 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000224 with socket.socket() as sock:
225 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000226 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000227
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000228 def test_match_hostname(self):
229 def ok(cert, hostname):
230 ssl.match_hostname(cert, hostname)
231 def fail(cert, hostname):
232 self.assertRaises(ssl.CertificateError,
233 ssl.match_hostname, cert, hostname)
234
235 cert = {'subject': ((('commonName', 'example.com'),),)}
236 ok(cert, 'example.com')
237 ok(cert, 'ExAmple.cOm')
238 fail(cert, 'www.example.com')
239 fail(cert, '.example.com')
240 fail(cert, 'example.org')
241 fail(cert, 'exampleXcom')
242
243 cert = {'subject': ((('commonName', '*.a.com'),),)}
244 ok(cert, 'foo.a.com')
245 fail(cert, 'bar.foo.a.com')
246 fail(cert, 'a.com')
247 fail(cert, 'Xa.com')
248 fail(cert, '.a.com')
249
250 cert = {'subject': ((('commonName', 'a.*.com'),),)}
251 ok(cert, 'a.foo.com')
252 fail(cert, 'a..com')
253 fail(cert, 'a.com')
254
255 cert = {'subject': ((('commonName', 'f*.com'),),)}
256 ok(cert, 'foo.com')
257 ok(cert, 'f.com')
258 fail(cert, 'bar.com')
259 fail(cert, 'foo.a.com')
260 fail(cert, 'bar.foo.com')
261
262 # Slightly fake real-world example
263 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
264 'subject': ((('commonName', 'linuxfrz.org'),),),
265 'subjectAltName': (('DNS', 'linuxfr.org'),
266 ('DNS', 'linuxfr.com'),
267 ('othername', '<unsupported>'))}
268 ok(cert, 'linuxfr.org')
269 ok(cert, 'linuxfr.com')
270 # Not a "DNS" entry
271 fail(cert, '<unsupported>')
272 # When there is a subjectAltName, commonName isn't used
273 fail(cert, 'linuxfrz.org')
274
275 # A pristine real-world example
276 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
277 'subject': ((('countryName', 'US'),),
278 (('stateOrProvinceName', 'California'),),
279 (('localityName', 'Mountain View'),),
280 (('organizationName', 'Google Inc'),),
281 (('commonName', 'mail.google.com'),))}
282 ok(cert, 'mail.google.com')
283 fail(cert, 'gmail.com')
284 # Only commonName is considered
285 fail(cert, 'California')
286
287 # Neither commonName nor subjectAltName
288 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
289 'subject': ((('countryName', 'US'),),
290 (('stateOrProvinceName', 'California'),),
291 (('localityName', 'Mountain View'),),
292 (('organizationName', 'Google Inc'),))}
293 fail(cert, 'mail.google.com')
294
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200295 # No DNS entry in subjectAltName but a commonName
296 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
297 'subject': ((('countryName', 'US'),),
298 (('stateOrProvinceName', 'California'),),
299 (('localityName', 'Mountain View'),),
300 (('commonName', 'mail.google.com'),)),
301 'subjectAltName': (('othername', 'blabla'), )}
302 ok(cert, 'mail.google.com')
303
304 # No DNS entry subjectAltName and no commonName
305 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
306 'subject': ((('countryName', 'US'),),
307 (('stateOrProvinceName', 'California'),),
308 (('localityName', 'Mountain View'),),
309 (('organizationName', 'Google Inc'),)),
310 'subjectAltName': (('othername', 'blabla'),)}
311 fail(cert, 'google.com')
312
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000313 # Empty cert / no cert
314 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
315 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
316
Antoine Pitroud5323212010-10-22 18:19:07 +0000317 def test_server_side(self):
318 # server_hostname doesn't work for server sockets
319 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000320 with socket.socket() as sock:
321 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
322 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000323
Antoine Pitrou152efa22010-05-16 18:19:27 +0000324class ContextTests(unittest.TestCase):
325
Antoine Pitrou23df4832010-08-04 17:14:06 +0000326 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000327 def test_constructor(self):
Victor Stinner3de49192011-05-09 00:42:58 +0200328 if hasattr(ssl, 'PROTOCOL_SSLv2'):
329 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000330 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
331 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
332 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
333 self.assertRaises(TypeError, ssl.SSLContext)
334 self.assertRaises(ValueError, ssl.SSLContext, -1)
335 self.assertRaises(ValueError, ssl.SSLContext, 42)
336
Antoine Pitrou23df4832010-08-04 17:14:06 +0000337 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000338 def test_protocol(self):
339 for proto in PROTOCOLS:
340 ctx = ssl.SSLContext(proto)
341 self.assertEqual(ctx.protocol, proto)
342
343 def test_ciphers(self):
344 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
345 ctx.set_ciphers("ALL")
346 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000347 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000348 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000349
Antoine Pitrou23df4832010-08-04 17:14:06 +0000350 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000351 def test_options(self):
352 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
353 # OP_ALL is the default value
354 self.assertEqual(ssl.OP_ALL, ctx.options)
355 ctx.options |= ssl.OP_NO_SSLv2
356 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
357 ctx.options)
358 ctx.options |= ssl.OP_NO_SSLv3
359 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
360 ctx.options)
361 if can_clear_options():
362 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
363 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
364 ctx.options)
365 ctx.options = 0
366 self.assertEqual(0, ctx.options)
367 else:
368 with self.assertRaises(ValueError):
369 ctx.options = 0
370
Antoine Pitrou152efa22010-05-16 18:19:27 +0000371 def test_verify(self):
372 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
373 # Default value
374 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
375 ctx.verify_mode = ssl.CERT_OPTIONAL
376 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
377 ctx.verify_mode = ssl.CERT_REQUIRED
378 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
379 ctx.verify_mode = ssl.CERT_NONE
380 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
381 with self.assertRaises(TypeError):
382 ctx.verify_mode = None
383 with self.assertRaises(ValueError):
384 ctx.verify_mode = 42
385
386 def test_load_cert_chain(self):
387 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
388 # Combined key and cert in a single file
389 ctx.load_cert_chain(CERTFILE)
390 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
391 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000392 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000393 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000394 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000395 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000396 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000397 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000398 ctx.load_cert_chain(EMPTYCERT)
399 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000400 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000401 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
402 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
403 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000404 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000405 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000406 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000407 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000408 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000409 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
410 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000411 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000412 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000413 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000414
415 def test_load_verify_locations(self):
416 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
417 ctx.load_verify_locations(CERTFILE)
418 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
419 ctx.load_verify_locations(BYTES_CERTFILE)
420 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
421 self.assertRaises(TypeError, ctx.load_verify_locations)
422 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000423 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000424 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000425 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000426 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000427 ctx.load_verify_locations(BADCERT)
428 ctx.load_verify_locations(CERTFILE, CAPATH)
429 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
430
Victor Stinner80f75e62011-01-29 11:31:20 +0000431 # Issue #10989: crash if the second argument type is invalid
432 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
433
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000434 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000435 def test_session_stats(self):
436 for proto in PROTOCOLS:
437 ctx = ssl.SSLContext(proto)
438 self.assertEqual(ctx.session_stats(), {
439 'number': 0,
440 'connect': 0,
441 'connect_good': 0,
442 'connect_renegotiate': 0,
443 'accept': 0,
444 'accept_good': 0,
445 'accept_renegotiate': 0,
446 'hits': 0,
447 'misses': 0,
448 'timeouts': 0,
449 'cache_full': 0,
450 })
451
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000452 def test_set_default_verify_paths(self):
453 # There's not much we can do to test that it acts as expected,
454 # so just check it doesn't crash or raise an exception.
455 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
456 ctx.set_default_verify_paths()
457
Antoine Pitrou152efa22010-05-16 18:19:27 +0000458
Bill Janssen6e027db2007-11-15 22:23:56 +0000459class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000460
Antoine Pitrou480a1242010-04-28 21:37:09 +0000461 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000462 with support.transient_internet("svn.python.org"):
463 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
464 cert_reqs=ssl.CERT_NONE)
465 try:
466 s.connect(("svn.python.org", 443))
467 self.assertEqual({}, s.getpeercert())
468 finally:
469 s.close()
470
471 # this should fail because we have no verification certs
472 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
473 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000474 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
475 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000476 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000477
Antoine Pitrou350c7222010-09-09 13:31:46 +0000478 # this should succeed because we specify the root cert
479 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
480 cert_reqs=ssl.CERT_REQUIRED,
481 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
482 try:
483 s.connect(("svn.python.org", 443))
484 self.assertTrue(s.getpeercert())
485 finally:
486 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000487
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000488 def test_connect_ex(self):
489 # Issue #11326: check connect_ex() implementation
490 with support.transient_internet("svn.python.org"):
491 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
492 cert_reqs=ssl.CERT_REQUIRED,
493 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
494 try:
495 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
496 self.assertTrue(s.getpeercert())
497 finally:
498 s.close()
499
500 def test_non_blocking_connect_ex(self):
501 # Issue #11326: non-blocking connect_ex() should allow handshake
502 # to proceed after the socket gets ready.
503 with support.transient_internet("svn.python.org"):
504 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
505 cert_reqs=ssl.CERT_REQUIRED,
506 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
507 do_handshake_on_connect=False)
508 try:
509 s.setblocking(False)
510 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +0000511 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
512 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000513 # Wait for connect to finish
514 select.select([], [s], [], 5.0)
515 # Non-blocking handshake
516 while True:
517 try:
518 s.do_handshake()
519 break
520 except ssl.SSLError as err:
521 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
522 select.select([s], [], [], 5.0)
523 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
524 select.select([], [s], [], 5.0)
525 else:
526 raise
527 # SSL established
528 self.assertTrue(s.getpeercert())
529 finally:
530 s.close()
531
Antoine Pitroub4410db2011-05-18 18:51:06 +0200532 def test_timeout_connect_ex(self):
533 # Issue #12065: on a timeout, connect_ex() should return the original
534 # errno (mimicking the behaviour of non-SSL sockets).
535 with support.transient_internet("svn.python.org"):
536 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
537 cert_reqs=ssl.CERT_REQUIRED,
538 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
539 do_handshake_on_connect=False)
540 try:
541 s.settimeout(0.0000001)
542 rc = s.connect_ex(('svn.python.org', 443))
543 if rc == 0:
544 self.skipTest("svn.python.org responded too quickly")
545 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
546 finally:
547 s.close()
548
Antoine Pitrou152efa22010-05-16 18:19:27 +0000549 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000550 with support.transient_internet("svn.python.org"):
551 # Same as test_connect, but with a separately created context
552 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
553 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
554 s.connect(("svn.python.org", 443))
555 try:
556 self.assertEqual({}, s.getpeercert())
557 finally:
558 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000559 # Same with a server hostname
560 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
561 server_hostname="svn.python.org")
562 if ssl.HAS_SNI:
563 s.connect(("svn.python.org", 443))
564 s.close()
565 else:
566 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000567 # This should fail because we have no verification certs
568 ctx.verify_mode = ssl.CERT_REQUIRED
569 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000570 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000571 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000572 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000573 # This should succeed because we specify the root cert
574 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
575 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
576 s.connect(("svn.python.org", 443))
577 try:
578 cert = s.getpeercert()
579 self.assertTrue(cert)
580 finally:
581 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000582
583 def test_connect_capath(self):
584 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000585 # NOTE: the subject hashing algorithm has been changed between
586 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
587 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000588 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000589 with support.transient_internet("svn.python.org"):
590 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
591 ctx.verify_mode = ssl.CERT_REQUIRED
592 ctx.load_verify_locations(capath=CAPATH)
593 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
594 s.connect(("svn.python.org", 443))
595 try:
596 cert = s.getpeercert()
597 self.assertTrue(cert)
598 finally:
599 s.close()
600 # Same with a bytes `capath` argument
601 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
602 ctx.verify_mode = ssl.CERT_REQUIRED
603 ctx.load_verify_locations(capath=BYTES_CAPATH)
604 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
605 s.connect(("svn.python.org", 443))
606 try:
607 cert = s.getpeercert()
608 self.assertTrue(cert)
609 finally:
610 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000611
Antoine Pitroue3220242010-04-24 11:13:53 +0000612 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
613 def test_makefile_close(self):
614 # Issue #5238: creating a file-like object with makefile() shouldn't
615 # delay closing the underlying "real socket" (here tested with its
616 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000617 with support.transient_internet("svn.python.org"):
618 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
619 ss.connect(("svn.python.org", 443))
620 fd = ss.fileno()
621 f = ss.makefile()
622 f.close()
623 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000624 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000625 # Closing the SSL socket should close the fd too
626 ss.close()
627 gc.collect()
628 with self.assertRaises(OSError) as e:
629 os.read(fd, 0)
630 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000631
Antoine Pitrou480a1242010-04-28 21:37:09 +0000632 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000633 with support.transient_internet("svn.python.org"):
634 s = socket.socket(socket.AF_INET)
635 s.connect(("svn.python.org", 443))
636 s.setblocking(False)
637 s = ssl.wrap_socket(s,
638 cert_reqs=ssl.CERT_NONE,
639 do_handshake_on_connect=False)
640 count = 0
641 while True:
642 try:
643 count += 1
644 s.do_handshake()
645 break
646 except ssl.SSLError as err:
647 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
648 select.select([s], [], [])
649 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
650 select.select([], [s], [])
651 else:
652 raise
653 s.close()
654 if support.verbose:
655 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000656
Antoine Pitrou480a1242010-04-28 21:37:09 +0000657 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +0200658 def _test_get_server_certificate(host, port, cert=None):
659 with support.transient_internet(host):
660 pem = ssl.get_server_certificate((host, port))
661 if not pem:
662 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200663
Antoine Pitrou15399c32011-04-28 19:23:55 +0200664 try:
665 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
666 except ssl.SSLError as x:
667 #should fail
668 if support.verbose:
669 sys.stdout.write("%s\n" % x)
670 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200671 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
672
Antoine Pitrou15399c32011-04-28 19:23:55 +0200673 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
674 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200675 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000676 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200677 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000678
Antoine Pitrou15399c32011-04-28 19:23:55 +0200679 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
680 if support.IPV6_ENABLED:
681 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000682
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000683 def test_ciphers(self):
684 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000685 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000686 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000687 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000688 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000689 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
690 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
691 s.connect(remote)
692 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000693 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000694 with socket.socket(socket.AF_INET) as sock:
695 s = ssl.wrap_socket(sock,
696 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
697 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000698
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000699 def test_algorithms(self):
700 # Issue #8484: all algorithms should be available when verifying a
701 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000702 # SHA256 was added in OpenSSL 0.9.8
703 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
704 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Victor Stinnerf332abb2011-01-08 03:16:05 +0000705 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
706 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000707 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000708 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitroua88c83c2010-09-07 20:42:19 +0000709 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
710 cert_reqs=ssl.CERT_REQUIRED,
711 ca_certs=sha256_cert,)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000712 try:
713 s.connect(remote)
714 if support.verbose:
715 sys.stdout.write("\nCipher with %r is %r\n" %
716 (remote, s.cipher()))
717 sys.stdout.write("Certificate is:\n%s\n" %
718 pprint.pformat(s.getpeercert()))
719 finally:
720 s.close()
721
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000722
723try:
724 import threading
725except ImportError:
726 _have_threads = False
727else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000728 _have_threads = True
729
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000730 from test.ssl_servers import make_https_server
731
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000732 class ThreadedEchoServer(threading.Thread):
733
734 class ConnectionHandler(threading.Thread):
735
736 """A mildly complicated class, because we want it to work both
737 with and without the SSL wrapper around the socket connection, so
738 that we can test the STARTTLS functionality."""
739
Bill Janssen6e027db2007-11-15 22:23:56 +0000740 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000741 self.server = server
742 self.running = False
743 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000744 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000745 self.sock.setblocking(1)
746 self.sslconn = None
747 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000748 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000749
Antoine Pitrou480a1242010-04-28 21:37:09 +0000750 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000751 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000752 self.sslconn = self.server.context.wrap_socket(
753 self.sock, server_side=True)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000754 except ssl.SSLError:
755 # XXX Various errors can have happened here, for example
756 # a mismatching protocol version, an invalid certificate,
757 # or a low-level bug. This should be made more discriminating.
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000758 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000759 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000760 self.running = False
761 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000762 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000763 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000764 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000765 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000766 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000767 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000768 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
769 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000770 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000771 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
772 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000773 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000774 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
775 return True
776
777 def read(self):
778 if self.sslconn:
779 return self.sslconn.read()
780 else:
781 return self.sock.recv(1024)
782
783 def write(self, bytes):
784 if self.sslconn:
785 return self.sslconn.write(bytes)
786 else:
787 return self.sock.send(bytes)
788
789 def close(self):
790 if self.sslconn:
791 self.sslconn.close()
792 else:
793 self.sock.close()
794
Antoine Pitrou480a1242010-04-28 21:37:09 +0000795 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000796 self.running = True
797 if not self.server.starttls_server:
798 if not self.wrap_conn():
799 return
800 while self.running:
801 try:
802 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000803 stripped = msg.strip()
804 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000805 # eof, so quit this handler
806 self.running = False
807 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000808 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000809 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000810 sys.stdout.write(" server: client closed connection\n")
811 self.close()
812 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000813 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000814 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000815 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000816 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000817 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000818 if not self.wrap_conn():
819 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000820 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000821 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000822 if support.verbose and self.server.connectionchatty:
823 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000824 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000825 self.sock = self.sslconn.unwrap()
826 self.sslconn = None
827 if support.verbose and self.server.connectionchatty:
828 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000829 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000830 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000831 self.server.connectionchatty):
832 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000833 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
834 % (msg, ctype, msg.lower(), ctype))
835 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000836 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000837 if self.server.chatty:
838 handle_error("Test server failure:\n")
839 self.close()
840 self.running = False
841 # normally, we'd just stop here, but for the test
842 # harness, we want to stop the server
843 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000844
Antoine Pitroub5218772010-05-21 09:56:06 +0000845 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000846 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000847 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000848 ciphers=None, context=None):
849 if context:
850 self.context = context
851 else:
852 self.context = ssl.SSLContext(ssl_version
853 if ssl_version is not None
854 else ssl.PROTOCOL_TLSv1)
855 self.context.verify_mode = (certreqs if certreqs is not None
856 else ssl.CERT_NONE)
857 if cacerts:
858 self.context.load_verify_locations(cacerts)
859 if certificate:
860 self.context.load_cert_chain(certificate)
861 if ciphers:
862 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000863 self.chatty = chatty
864 self.connectionchatty = connectionchatty
865 self.starttls_server = starttls_server
866 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000867 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000868 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000869 self.active = False
870 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000871 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000872
Antoine Pitrou480a1242010-04-28 21:37:09 +0000873 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000874 self.flag = flag
875 threading.Thread.start(self)
876
Antoine Pitrou480a1242010-04-28 21:37:09 +0000877 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000878 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000879 self.sock.listen(5)
880 self.active = True
881 if self.flag:
882 # signal an event
883 self.flag.set()
884 while self.active:
885 try:
886 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000887 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000888 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000889 + repr(connaddr) + '\n')
890 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000891 handler.start()
892 except socket.timeout:
893 pass
894 except KeyboardInterrupt:
895 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000896 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000897
Antoine Pitrou480a1242010-04-28 21:37:09 +0000898 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000899 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000900
Bill Janssen54cc54c2007-12-14 22:08:56 +0000901 class AsyncoreEchoServer(threading.Thread):
902
903 # this one's based on asyncore.dispatcher
904
905 class EchoServer (asyncore.dispatcher):
906
907 class ConnectionHandler (asyncore.dispatcher_with_send):
908
909 def __init__(self, conn, certfile):
910 self.socket = ssl.wrap_socket(conn, server_side=True,
911 certfile=certfile,
912 do_handshake_on_connect=False)
913 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000914 self._ssl_accepting = True
915 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000916
917 def readable(self):
918 if isinstance(self.socket, ssl.SSLSocket):
919 while self.socket.pending() > 0:
920 self.handle_read_event()
921 return True
922
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000923 def _do_ssl_handshake(self):
924 try:
925 self.socket.do_handshake()
926 except ssl.SSLError as err:
927 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
928 ssl.SSL_ERROR_WANT_WRITE):
929 return
930 elif err.args[0] == ssl.SSL_ERROR_EOF:
931 return self.handle_close()
932 raise
933 except socket.error as err:
934 if err.args[0] == errno.ECONNABORTED:
935 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +0000936 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +0000937 self._ssl_accepting = False
938
939 def handle_read(self):
940 if self._ssl_accepting:
941 self._do_ssl_handshake()
942 else:
943 data = self.recv(1024)
944 if support.verbose:
945 sys.stdout.write(" server: read %s from client\n" % repr(data))
946 if not data:
947 self.close()
948 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000949 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +0000950
951 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +0000952 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000953 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000954 sys.stdout.write(" server: closed connection %s\n" % self.socket)
955
956 def handle_error(self):
957 raise
958
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000959 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000960 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000961 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
962 self.port = support.bind_port(sock, '')
963 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000964 self.listen(5)
965
Giampaolo Rodolà977c7072010-10-04 21:08:36 +0000966 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000967 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +0000968 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
969 self.ConnectionHandler(sock_obj, self.certfile)
970
971 def handle_error(self):
972 raise
973
Trent Nelson78520002008-04-10 20:54:35 +0000974 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000975 self.flag = None
976 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +0000977 self.server = self.EchoServer(certfile)
978 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +0000979 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000980 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +0000981
982 def __str__(self):
983 return "<%s %s>" % (self.__class__.__name__, self.server)
984
985 def start (self, flag=None):
986 self.flag = flag
987 threading.Thread.start(self)
988
Antoine Pitrou480a1242010-04-28 21:37:09 +0000989 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +0000990 self.active = True
991 if self.flag:
992 self.flag.set()
993 while self.active:
994 try:
995 asyncore.loop(1)
996 except:
997 pass
998
Antoine Pitrou480a1242010-04-28 21:37:09 +0000999 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001000 self.active = False
1001 self.server.close()
1002
Antoine Pitrou480a1242010-04-28 21:37:09 +00001003 def bad_cert_test(certfile):
1004 """
1005 Launch a server with CERT_REQUIRED, and check that trying to
1006 connect to it with the given client certificate fails.
1007 """
Trent Nelson78520002008-04-10 20:54:35 +00001008 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001009 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +00001010 cacerts=CERTFILE, chatty=False,
1011 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001012 flag = threading.Event()
1013 server.start(flag)
1014 # wait for it to start
1015 flag.wait()
1016 # try to connect
1017 try:
Thomas Woutersed03b412007-08-28 21:37:11 +00001018 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001019 with socket.socket() as sock:
1020 s = ssl.wrap_socket(sock,
1021 certfile=certfile,
1022 ssl_version=ssl.PROTOCOL_TLSv1)
1023 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001024 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001025 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001026 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +00001027 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001028 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +00001029 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001030 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001031 if x.errno != errno.ENOENT:
1032 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001033 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001034 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001035 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001036 raise AssertionError("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001037 finally:
1038 server.stop()
1039 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001040
Antoine Pitroub5218772010-05-21 09:56:06 +00001041 def server_params_test(client_context, server_context, indata=b"FOO\n",
1042 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001043 """
1044 Launch a server, connect a client to it and try various reads
1045 and writes.
1046 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001047 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001048 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001049 connectionchatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001050 flag = threading.Event()
1051 server.start(flag)
1052 # wait for it to start
1053 flag.wait()
1054 # try to connect
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001055 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001056 s = client_context.wrap_socket(socket.socket())
Trent Nelson78520002008-04-10 20:54:35 +00001057 s.connect((HOST, server.port))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001058 for arg in [indata, bytearray(indata), memoryview(indata)]:
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001059 if connectionchatty:
1060 if support.verbose:
1061 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001062 " client: sending %r...\n" % indata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001063 s.write(arg)
1064 outdata = s.read()
1065 if connectionchatty:
1066 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001067 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001068 if outdata != indata.lower():
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001069 raise AssertionError(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001070 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1071 % (outdata[:20], len(outdata),
1072 indata[:20].lower(), len(indata)))
1073 s.write(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001074 if connectionchatty:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001075 if support.verbose:
Bill Janssen6e027db2007-11-15 22:23:56 +00001076 sys.stdout.write(" client: closing connection.\n")
1077 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078 finally:
1079 server.stop()
1080 server.join()
Thomas Woutersed03b412007-08-28 21:37:11 +00001081
Antoine Pitroub5218772010-05-21 09:56:06 +00001082 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1083 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001084 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001085 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001086 certtype = {
1087 ssl.CERT_NONE: "CERT_NONE",
1088 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1089 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1090 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001091 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001092 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001093 sys.stdout.write(formatstr %
1094 (ssl.get_protocol_name(client_protocol),
1095 ssl.get_protocol_name(server_protocol),
1096 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001097 client_context = ssl.SSLContext(client_protocol)
1098 client_context.options = ssl.OP_ALL | client_options
1099 server_context = ssl.SSLContext(server_protocol)
1100 server_context.options = ssl.OP_ALL | server_options
1101 for ctx in (client_context, server_context):
1102 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001103 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1104 # will send an SSLv3 hello (rather than SSLv2) starting from
1105 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001106 ctx.set_ciphers("ALL")
1107 ctx.load_cert_chain(CERTFILE)
1108 ctx.load_verify_locations(CERTFILE)
1109 try:
1110 server_params_test(client_context, server_context,
1111 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001112 # Protocol mismatch can result in either an SSLError, or a
1113 # "Connection reset by peer" error.
1114 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001115 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001116 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001117 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001118 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001119 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001120 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001121 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001122 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001123 "Client protocol %s succeeded with server protocol %s!"
1124 % (ssl.get_protocol_name(client_protocol),
1125 ssl.get_protocol_name(server_protocol)))
1126
1127
Bill Janssen6e027db2007-11-15 22:23:56 +00001128 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001129
Antoine Pitrou23df4832010-08-04 17:14:06 +00001130 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001131 def test_echo(self):
1132 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001133 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001134 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001135 for protocol in PROTOCOLS:
1136 context = ssl.SSLContext(protocol)
1137 context.load_cert_chain(CERTFILE)
1138 server_params_test(context, context,
1139 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001140
Antoine Pitrou480a1242010-04-28 21:37:09 +00001141 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001142 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001143 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001144 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1145 context.verify_mode = ssl.CERT_REQUIRED
1146 context.load_verify_locations(CERTFILE)
1147 context.load_cert_chain(CERTFILE)
1148 server = ThreadedEchoServer(context=context, chatty=False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001149 flag = threading.Event()
1150 server.start(flag)
1151 # wait for it to start
1152 flag.wait()
1153 # try to connect
1154 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001155 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001156 s.connect((HOST, server.port))
1157 cert = s.getpeercert()
1158 self.assertTrue(cert, "Can't get peer certificate.")
1159 cipher = s.cipher()
1160 if support.verbose:
1161 sys.stdout.write(pprint.pformat(cert) + '\n')
1162 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1163 if 'subject' not in cert:
1164 self.fail("No subject field in certificate: %s." %
1165 pprint.pformat(cert))
1166 if ((('organizationName', 'Python Software Foundation'),)
1167 not in cert['subject']):
1168 self.fail(
1169 "Missing or invalid 'organizationName' field in certificate subject; "
1170 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001171 self.assertIn('notBefore', cert)
1172 self.assertIn('notAfter', cert)
1173 before = ssl.cert_time_to_seconds(cert['notBefore'])
1174 after = ssl.cert_time_to_seconds(cert['notAfter'])
1175 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001176 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001177 finally:
1178 server.stop()
1179 server.join()
1180
Antoine Pitrou480a1242010-04-28 21:37:09 +00001181 def test_empty_cert(self):
1182 """Connecting with an empty cert file"""
1183 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1184 "nullcert.pem"))
1185 def test_malformed_cert(self):
1186 """Connecting with a badly formatted certificate (syntax error)"""
1187 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1188 "badcert.pem"))
1189 def test_nonexisting_cert(self):
1190 """Connecting with a non-existing cert file"""
1191 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1192 "wrongcert.pem"))
1193 def test_malformed_key(self):
1194 """Connecting with a badly formatted key (syntax error)"""
1195 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1196 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001197
Antoine Pitrou480a1242010-04-28 21:37:09 +00001198 def test_rude_shutdown(self):
1199 """A brutal shutdown of an SSL server should raise an IOError
1200 in the client when attempting handshake.
1201 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001202 listener_ready = threading.Event()
1203 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001204
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001205 s = socket.socket()
1206 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001207
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001208 # `listener` runs in a thread. It sits in an accept() until
1209 # the main thread connects. Then it rudely closes the socket,
1210 # and sets Event `listener_gone` to let the main thread know
1211 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001212 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001213 s.listen(5)
1214 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001215 newsock, addr = s.accept()
1216 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001217 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001218 listener_gone.set()
1219
1220 def connector():
1221 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001222 with socket.socket() as c:
1223 c.connect((HOST, port))
1224 listener_gone.wait()
1225 try:
1226 ssl_sock = ssl.wrap_socket(c)
1227 except IOError:
1228 pass
1229 else:
1230 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001231
1232 t = threading.Thread(target=listener)
1233 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001234 try:
1235 connector()
1236 finally:
1237 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001238
Antoine Pitrou23df4832010-08-04 17:14:06 +00001239 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02001240 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
1241 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001242 def test_protocol_sslv2(self):
1243 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001244 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001245 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001246 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1247 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1248 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1249 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1250 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1251 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001252 # SSLv23 client with specific SSL options
1253 if no_sslv2_implies_sslv3_hello():
1254 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1255 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1256 client_options=ssl.OP_NO_SSLv2)
1257 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1258 client_options=ssl.OP_NO_SSLv3)
1259 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1260 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001261
Antoine Pitrou23df4832010-08-04 17:14:06 +00001262 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001263 def test_protocol_sslv23(self):
1264 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001265 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001266 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02001267 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1268 try:
1269 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
1270 except (ssl.SSLError, socket.error) as x:
1271 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1272 if support.verbose:
1273 sys.stdout.write(
1274 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1275 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001276 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1277 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1278 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001279
Antoine Pitrou480a1242010-04-28 21:37:09 +00001280 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1281 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1282 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001283
Antoine Pitrou480a1242010-04-28 21:37:09 +00001284 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1285 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1286 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001287
Antoine Pitroub5218772010-05-21 09:56:06 +00001288 # Server with specific SSL options
1289 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1290 server_options=ssl.OP_NO_SSLv3)
1291 # Will choose TLSv1
1292 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1293 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1294 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1295 server_options=ssl.OP_NO_TLSv1)
1296
1297
Antoine Pitrou23df4832010-08-04 17:14:06 +00001298 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001299 def test_protocol_sslv3(self):
1300 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001301 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001302 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001303 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1304 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1305 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001306 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1307 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001308 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False)
1309 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001310 if no_sslv2_implies_sslv3_hello():
1311 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1312 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1313 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001314
Antoine Pitrou23df4832010-08-04 17:14:06 +00001315 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001316 def test_protocol_tlsv1(self):
1317 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001318 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001319 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001320 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1321 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1322 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001323 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1324 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001325 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1326 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001327
Antoine Pitrou480a1242010-04-28 21:37:09 +00001328 def test_starttls(self):
1329 """Switching from clear text to encrypted and back again."""
1330 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 +00001331
Trent Nelson78520002008-04-10 20:54:35 +00001332 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001333 ssl_version=ssl.PROTOCOL_TLSv1,
1334 starttls_server=True,
1335 chatty=True,
1336 connectionchatty=True)
1337 flag = threading.Event()
1338 server.start(flag)
1339 # wait for it to start
1340 flag.wait()
1341 # try to connect
1342 wrapped = False
1343 try:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001344 s = socket.socket()
1345 s.setblocking(1)
1346 s.connect((HOST, server.port))
1347 if support.verbose:
1348 sys.stdout.write("\n")
1349 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001350 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001351 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001352 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001353 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001354 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001355 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001356 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001357 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001358 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001359 msg = outdata.strip().lower()
1360 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1361 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001362 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001363 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001364 " client: read %r from server, starting TLS...\n"
1365 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001366 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1367 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001368 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1369 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001370 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001371 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001372 " client: read %r from server, ending TLS...\n"
1373 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001374 s = conn.unwrap()
1375 wrapped = False
1376 else:
1377 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001378 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001379 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001380 if support.verbose:
1381 sys.stdout.write(" client: closing connection.\n")
1382 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001383 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001384 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001385 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001386 if wrapped:
1387 conn.close()
1388 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001389 s.close()
1390 finally:
1391 server.stop()
1392 server.join()
1393
Antoine Pitrou480a1242010-04-28 21:37:09 +00001394 def test_socketserver(self):
1395 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001396 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001397 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001398 if support.verbose:
1399 sys.stdout.write('\n')
1400 with open(CERTFILE, 'rb') as f:
1401 d1 = f.read()
1402 d2 = ''
1403 # now fetch the same data from the HTTPS server
1404 url = 'https://%s:%d/%s' % (
1405 HOST, server.port, os.path.split(CERTFILE)[1])
1406 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001407 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001408 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001409 if dlen and (int(dlen) > 0):
1410 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001411 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001412 sys.stdout.write(
1413 " client: read %d bytes from remote server '%s'\n"
1414 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001415 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001416 f.close()
1417 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001418
Antoine Pitrou480a1242010-04-28 21:37:09 +00001419 def test_asyncore_server(self):
1420 """Check the example asyncore integration."""
1421 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001422
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001423 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001424 sys.stdout.write("\n")
1425
Antoine Pitrou480a1242010-04-28 21:37:09 +00001426 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001427 server = AsyncoreEchoServer(CERTFILE)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001428 flag = threading.Event()
1429 server.start(flag)
1430 # wait for it to start
1431 flag.wait()
1432 # try to connect
1433 try:
1434 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001435 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001436 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001437 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001438 " client: sending %r...\n" % indata)
1439 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001440 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001441 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001442 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001443 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001444 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001445 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1446 % (outdata[:20], len(outdata),
1447 indata[:20].lower(), len(indata)))
1448 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001449 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001450 sys.stdout.write(" client: closing connection.\n")
1451 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001452 if support.verbose:
1453 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001454 finally:
Antoine Pitroued986362010-08-15 23:28:10 +00001455 if support.verbose:
1456 sys.stdout.write(" cleanup: stopping server.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001457 server.stop()
Antoine Pitroued986362010-08-15 23:28:10 +00001458 if support.verbose:
1459 sys.stdout.write(" cleanup: joining server thread.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001460 server.join()
Antoine Pitroued986362010-08-15 23:28:10 +00001461 if support.verbose:
1462 sys.stdout.write(" cleanup: successfully joined.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001463
Antoine Pitrou480a1242010-04-28 21:37:09 +00001464 def test_recv_send(self):
1465 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001466 if support.verbose:
1467 sys.stdout.write("\n")
1468
1469 server = ThreadedEchoServer(CERTFILE,
1470 certreqs=ssl.CERT_NONE,
1471 ssl_version=ssl.PROTOCOL_TLSv1,
1472 cacerts=CERTFILE,
1473 chatty=True,
1474 connectionchatty=False)
1475 flag = threading.Event()
1476 server.start(flag)
1477 # wait for it to start
1478 flag.wait()
1479 # try to connect
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001480 s = ssl.wrap_socket(socket.socket(),
1481 server_side=False,
1482 certfile=CERTFILE,
1483 ca_certs=CERTFILE,
1484 cert_reqs=ssl.CERT_NONE,
1485 ssl_version=ssl.PROTOCOL_TLSv1)
1486 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001487 try:
Bill Janssen58afe4c2008-09-08 16:45:19 +00001488 # helper methods for standardising recv* method signatures
1489 def _recv_into():
1490 b = bytearray(b"\0"*100)
1491 count = s.recv_into(b)
1492 return b[:count]
1493
1494 def _recvfrom_into():
1495 b = bytearray(b"\0"*100)
1496 count, addr = s.recvfrom_into(b)
1497 return b[:count]
1498
1499 # (name, method, whether to expect success, *args)
1500 send_methods = [
1501 ('send', s.send, True, []),
1502 ('sendto', s.sendto, False, ["some.address"]),
1503 ('sendall', s.sendall, True, []),
1504 ]
1505 recv_methods = [
1506 ('recv', s.recv, True, []),
1507 ('recvfrom', s.recvfrom, False, ["some.address"]),
1508 ('recv_into', _recv_into, True, []),
1509 ('recvfrom_into', _recvfrom_into, False, []),
1510 ]
1511 data_prefix = "PREFIX_"
1512
1513 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001514 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001515 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001516 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001517 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001518 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001519 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001520 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001521 "<<{outdata:r}>> ({nout:d}) received; "
1522 "expected <<{indata:r}>> ({nin:d})\n".format(
1523 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001524 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001525 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001526 )
1527 )
1528 except ValueError as e:
1529 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001530 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001531 "Failed to send with method <<{name:s}>>; "
1532 "expected to succeed.\n".format(name=meth_name)
1533 )
1534 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001535 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001536 "Method <<{name:s}>> failed with unexpected "
1537 "exception message: {exp:s}\n".format(
1538 name=meth_name, exp=e
1539 )
1540 )
1541
1542 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001543 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001544 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001545 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001546 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001547 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001548 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001549 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001550 "<<{outdata:r}>> ({nout:d}) received; "
1551 "expected <<{indata:r}>> ({nin:d})\n".format(
1552 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001553 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001554 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001555 )
1556 )
1557 except ValueError as e:
1558 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001559 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001560 "Failed to receive with method <<{name:s}>>; "
1561 "expected to succeed.\n".format(name=meth_name)
1562 )
1563 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001564 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001565 "Method <<{name:s}>> failed with unexpected "
1566 "exception message: {exp:s}\n".format(
1567 name=meth_name, exp=e
1568 )
1569 )
1570 # consume data
1571 s.read()
1572
Antoine Pitrou480a1242010-04-28 21:37:09 +00001573 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001574 s.close()
1575 finally:
1576 server.stop()
1577 server.join()
1578
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001579 def test_handshake_timeout(self):
1580 # Issue #5103: SSL handshake must respect the socket timeout
1581 server = socket.socket(socket.AF_INET)
1582 host = "127.0.0.1"
1583 port = support.bind_port(server)
1584 started = threading.Event()
1585 finish = False
1586
1587 def serve():
1588 server.listen(5)
1589 started.set()
1590 conns = []
1591 while not finish:
1592 r, w, e = select.select([server], [], [], 0.1)
1593 if server in r:
1594 # Let the socket hang around rather than having
1595 # it closed by garbage collection.
1596 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001597 for sock in conns:
1598 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001599
1600 t = threading.Thread(target=serve)
1601 t.start()
1602 started.wait()
1603
1604 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001605 try:
1606 c = socket.socket(socket.AF_INET)
1607 c.settimeout(0.2)
1608 c.connect((host, port))
1609 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001610 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001611 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001612 finally:
1613 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001614 try:
1615 c = socket.socket(socket.AF_INET)
1616 c = ssl.wrap_socket(c)
1617 c.settimeout(0.2)
1618 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001619 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001620 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001621 finally:
1622 c.close()
1623 finally:
1624 finish = True
1625 t.join()
1626 server.close()
1627
Bill Janssen58afe4c2008-09-08 16:45:19 +00001628
Thomas Woutersed03b412007-08-28 21:37:11 +00001629def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001630 if support.verbose:
1631 plats = {
1632 'Linux': platform.linux_distribution,
1633 'Mac': platform.mac_ver,
1634 'Windows': platform.win32_ver,
1635 }
1636 for name, func in plats.items():
1637 plat = func()
1638 if plat and plat[0]:
1639 plat = '%s %r' % (name, plat)
1640 break
1641 else:
1642 plat = repr(platform.platform())
1643 print("test_ssl: testing with %r %r" %
1644 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1645 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001646 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001647
Antoine Pitrou152efa22010-05-16 18:19:27 +00001648 for filename in [
1649 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1650 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1651 BADCERT, BADKEY, EMPTYCERT]:
1652 if not os.path.exists(filename):
1653 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001654
Antoine Pitrou152efa22010-05-16 18:19:27 +00001655 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001656
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001657 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001658 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001659
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001660 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001661 thread_info = support.threading_setup()
1662 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001663 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001664
Antoine Pitrou480a1242010-04-28 21:37:09 +00001665 try:
1666 support.run_unittest(*tests)
1667 finally:
1668 if _have_threads:
1669 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001670
1671if __name__ == "__main__":
1672 test_main()