blob: d90e46dc49fc85b2962655dc24568212c65129a9 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +00009import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000010import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000011import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000012import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000013import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000014import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000015import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000016import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000017import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000018import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000019import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000020
Antoine Pitrou05d936d2010-10-13 11:38:36 +000021ssl = support.import_module("ssl")
22
23PROTOCOLS = [
Victor Stinner17ca3232011-05-10 00:48:41 +020024 ssl.PROTOCOL_SSLv3,
Antoine Pitrou05d936d2010-10-13 11:38:36 +000025 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
26]
Victor Stinner17ca3232011-05-10 00:48:41 +020027if hasattr(ssl, 'PROTOCOL_SSLv2'):
28 PROTOCOLS.append(ssl.PROTOCOL_SSLv2)
Thomas Woutersed03b412007-08-28 21:37:11 +000029
Benjamin Petersonee8712c2008-05-20 21:35:26 +000030HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000031
32data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000033
Antoine Pitrou81564092010-10-08 23:06:24 +000034# The custom key and certificate files used in test_ssl are generated
35# using Lib/test/make_ssl_certs.py.
36# Other certificates are simply fetched from the Internet servers they
37# are meant to authenticate.
38
Antoine Pitrou152efa22010-05-16 18:19:27 +000039CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000040BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000041ONLYCERT = data_file("ssl_cert.pem")
42ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000043BYTES_ONLYCERT = os.fsencode(ONLYCERT)
44BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +000045CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000046BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000047
48SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
49
50EMPTYCERT = data_file("nullcert.pem")
51BADCERT = data_file("badcert.pem")
52WRONGCERT = data_file("XXXnonexisting.pem")
53BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020054NOKIACERT = data_file("nokia.pem")
Georg Brandlec3c1032014-09-30 14:04:51 +020055NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000056
Thomas Woutersed03b412007-08-28 21:37:11 +000057
Thomas Woutersed03b412007-08-28 21:37:11 +000058def handle_error(prefix):
59 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000060 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000061 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000062
Antoine Pitroub5218772010-05-21 09:56:06 +000063def can_clear_options():
64 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020065 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000066
67def no_sslv2_implies_sslv3_hello():
68 # 0.9.7h or higher
69 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
70
Thomas Woutersed03b412007-08-28 21:37:11 +000071
Antoine Pitrou23df4832010-08-04 17:14:06 +000072# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
73def skip_if_broken_ubuntu_ssl(func):
Victor Stinner17ca3232011-05-10 00:48:41 +020074 if hasattr(ssl, 'PROTOCOL_SSLv2'):
75 @functools.wraps(func)
76 def f(*args, **kwargs):
77 try:
78 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
79 except ssl.SSLError:
80 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
81 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
82 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
83 return func(*args, **kwargs)
84 return f
85 else:
86 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +000087
88
Antoine Pitrou152efa22010-05-16 18:19:27 +000089class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +000090
Antoine Pitrou480a1242010-04-28 21:37:09 +000091 def test_constants(self):
Victor Stinneree18b6f2011-05-10 00:38:00 +020092 #ssl.PROTOCOL_SSLv2
Thomas Wouters1b7f8912007-09-19 03:06:30 +000093 ssl.PROTOCOL_SSLv23
94 ssl.PROTOCOL_SSLv3
95 ssl.PROTOCOL_TLSv1
96 ssl.CERT_NONE
97 ssl.CERT_OPTIONAL
98 ssl.CERT_REQUIRED
Antoine Pitroud5323212010-10-22 18:19:07 +000099 self.assertIn(ssl.HAS_SNI, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000100
Antoine Pitrou480a1242010-04-28 21:37:09 +0000101 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000102 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000103 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000104 sys.stdout.write("\n RAND_status is %d (%s)\n"
105 % (v, (v and "sufficient randomness") or
106 "insufficient randomness"))
Jesus Ceac8754a12012-09-11 02:00:58 +0200107 self.assertRaises(TypeError, ssl.RAND_egd, 1)
108 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000109 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000110
Antoine Pitrou480a1242010-04-28 21:37:09 +0000111 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000112 # note that this uses an 'unofficial' function in _ssl.c,
113 # provided solely for this test, to exercise the certificate
114 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000115 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000116 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000117 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200118 self.assertEqual(p['issuer'],
119 ((('countryName', 'XY'),),
120 (('localityName', 'Castle Anthrax'),),
121 (('organizationName', 'Python Software Foundation'),),
122 (('commonName', 'localhost'),))
123 )
124 self.assertEqual(p['notAfter'], 'Oct 5 23:01:56 2020 GMT')
125 self.assertEqual(p['notBefore'], 'Oct 8 23:01:56 2010 GMT')
126 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
127 self.assertEqual(p['subject'],
128 ((('countryName', 'XY'),),
129 (('localityName', 'Castle Anthrax'),),
130 (('organizationName', 'Python Software Foundation'),),
131 (('commonName', 'localhost'),))
132 )
133 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
134 # Issue #13034: the subjectAltName in some certificates
135 # (notably projects.developer.nokia.com:443) wasn't parsed
136 p = ssl._ssl._test_decode_cert(NOKIACERT)
137 if support.verbose:
138 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
139 self.assertEqual(p['subjectAltName'],
140 (('DNS', 'projects.developer.nokia.com'),
141 ('DNS', 'projects.forum.nokia.com'))
142 )
Thomas Woutersed03b412007-08-28 21:37:11 +0000143
Georg Brandlec3c1032014-09-30 14:04:51 +0200144 def test_parse_cert_CVE_2013_4073(self):
145 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
146 if support.verbose:
147 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
148 subject = ((('countryName', 'US'),),
149 (('stateOrProvinceName', 'Oregon'),),
150 (('localityName', 'Beaverton'),),
151 (('organizationName', 'Python Software Foundation'),),
152 (('organizationalUnitName', 'Python Core Development'),),
153 (('commonName', 'null.python.org\x00example.org'),),
154 (('emailAddress', 'python-dev@python.org'),))
155 self.assertEqual(p['subject'], subject)
156 self.assertEqual(p['issuer'], subject)
157 self.assertEqual(p['subjectAltName'],
158 (('DNS', 'altnull.python.org\x00example.com'),
159 ('email', 'null@python.org\x00user@example.org'),
160 ('URI', 'http://null.python.org\x00http://example.org'),
161 ('IP Address', '192.0.2.1'),
162 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
163 )
164
Antoine Pitrou480a1242010-04-28 21:37:09 +0000165 def test_DER_to_PEM(self):
166 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
167 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000168 d1 = ssl.PEM_cert_to_DER_cert(pem)
169 p2 = ssl.DER_cert_to_PEM_cert(d1)
170 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000171 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000172 if not p2.startswith(ssl.PEM_HEADER + '\n'):
173 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
174 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
175 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000176
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000177 def test_openssl_version(self):
178 n = ssl.OPENSSL_VERSION_NUMBER
179 t = ssl.OPENSSL_VERSION_INFO
180 s = ssl.OPENSSL_VERSION
181 self.assertIsInstance(n, int)
182 self.assertIsInstance(t, tuple)
183 self.assertIsInstance(s, str)
184 # Some sanity checks follow
185 # >= 0.9
186 self.assertGreaterEqual(n, 0x900000)
187 # < 2.0
188 self.assertLess(n, 0x20000000)
189 major, minor, fix, patch, status = t
190 self.assertGreaterEqual(major, 0)
191 self.assertLess(major, 2)
192 self.assertGreaterEqual(minor, 0)
193 self.assertLess(minor, 256)
194 self.assertGreaterEqual(fix, 0)
195 self.assertLess(fix, 256)
196 self.assertGreaterEqual(patch, 0)
197 self.assertLessEqual(patch, 26)
198 self.assertGreaterEqual(status, 0)
199 self.assertLessEqual(status, 15)
200 # Version string as returned by OpenSSL, the format might change
201 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
202 (s, t))
203
Antoine Pitrou9d543662010-04-23 23:10:32 +0000204 @support.cpython_only
205 def test_refcycle(self):
206 # Issue #7943: an SSL object doesn't create reference cycles with
207 # itself.
208 s = socket.socket(socket.AF_INET)
209 ss = ssl.wrap_socket(s)
210 wr = weakref.ref(ss)
211 del ss
212 self.assertEqual(wr(), None)
213
Antoine Pitroua468adc2010-09-14 14:43:44 +0000214 def test_wrapped_unconnected(self):
215 # Methods on an unconnected SSLSocket propagate the original
216 # socket.error raise by the underlying socket object.
217 s = socket.socket(socket.AF_INET)
218 ss = ssl.wrap_socket(s)
219 self.assertRaises(socket.error, ss.recv, 1)
220 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
221 self.assertRaises(socket.error, ss.recvfrom, 1)
222 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
223 self.assertRaises(socket.error, ss.send, b'x')
224 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
225
Antoine Pitrou40f08742010-04-24 22:04:40 +0000226 def test_timeout(self):
227 # Issue #8524: when creating an SSL socket, the timeout of the
228 # original socket should be retained.
229 for timeout in (None, 0.0, 5.0):
230 s = socket.socket(socket.AF_INET)
231 s.settimeout(timeout)
232 ss = ssl.wrap_socket(s)
233 self.assertEqual(timeout, ss.gettimeout())
234
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000235 def test_errors(self):
236 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000237 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000238 "certfile must be specified",
239 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000240 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000241 "certfile must be specified for server-side operations",
242 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000243 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000244 "certfile must be specified for server-side operations",
245 ssl.wrap_socket, sock, server_side=True, certfile="")
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000246 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000247 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000248 s.connect, (HOST, 8080))
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000249 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000250 with socket.socket() as sock:
251 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000252 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000253 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000254 with socket.socket() as sock:
255 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000256 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000257 with self.assertRaises(IOError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000258 with socket.socket() as sock:
259 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000260 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000261
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000262 def test_match_hostname(self):
263 def ok(cert, hostname):
264 ssl.match_hostname(cert, hostname)
265 def fail(cert, hostname):
266 self.assertRaises(ssl.CertificateError,
267 ssl.match_hostname, cert, hostname)
268
269 cert = {'subject': ((('commonName', 'example.com'),),)}
270 ok(cert, 'example.com')
271 ok(cert, 'ExAmple.cOm')
272 fail(cert, 'www.example.com')
273 fail(cert, '.example.com')
274 fail(cert, 'example.org')
275 fail(cert, 'exampleXcom')
276
277 cert = {'subject': ((('commonName', '*.a.com'),),)}
278 ok(cert, 'foo.a.com')
279 fail(cert, 'bar.foo.a.com')
280 fail(cert, 'a.com')
281 fail(cert, 'Xa.com')
282 fail(cert, '.a.com')
283
284 cert = {'subject': ((('commonName', 'a.*.com'),),)}
285 ok(cert, 'a.foo.com')
286 fail(cert, 'a..com')
287 fail(cert, 'a.com')
288
289 cert = {'subject': ((('commonName', 'f*.com'),),)}
290 ok(cert, 'foo.com')
291 ok(cert, 'f.com')
292 fail(cert, 'bar.com')
293 fail(cert, 'foo.a.com')
294 fail(cert, 'bar.foo.com')
295
Georg Brandlec3c1032014-09-30 14:04:51 +0200296 # NULL bytes are bad, CVE-2013-4073
297 cert = {'subject': ((('commonName',
298 'null.python.org\x00example.org'),),)}
299 ok(cert, 'null.python.org\x00example.org') # or raise an error?
300 fail(cert, 'example.org')
301 fail(cert, 'null.python.org')
302
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000303 # Slightly fake real-world example
304 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
305 'subject': ((('commonName', 'linuxfrz.org'),),),
306 'subjectAltName': (('DNS', 'linuxfr.org'),
307 ('DNS', 'linuxfr.com'),
308 ('othername', '<unsupported>'))}
309 ok(cert, 'linuxfr.org')
310 ok(cert, 'linuxfr.com')
311 # Not a "DNS" entry
312 fail(cert, '<unsupported>')
313 # When there is a subjectAltName, commonName isn't used
314 fail(cert, 'linuxfrz.org')
315
316 # A pristine real-world example
317 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
318 'subject': ((('countryName', 'US'),),
319 (('stateOrProvinceName', 'California'),),
320 (('localityName', 'Mountain View'),),
321 (('organizationName', 'Google Inc'),),
322 (('commonName', 'mail.google.com'),))}
323 ok(cert, 'mail.google.com')
324 fail(cert, 'gmail.com')
325 # Only commonName is considered
326 fail(cert, 'California')
327
328 # Neither commonName nor subjectAltName
329 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
330 'subject': ((('countryName', 'US'),),
331 (('stateOrProvinceName', 'California'),),
332 (('localityName', 'Mountain View'),),
333 (('organizationName', 'Google Inc'),))}
334 fail(cert, 'mail.google.com')
335
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200336 # No DNS entry in subjectAltName but a commonName
337 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
338 'subject': ((('countryName', 'US'),),
339 (('stateOrProvinceName', 'California'),),
340 (('localityName', 'Mountain View'),),
341 (('commonName', 'mail.google.com'),)),
342 'subjectAltName': (('othername', 'blabla'), )}
343 ok(cert, 'mail.google.com')
344
345 # No DNS entry subjectAltName and no commonName
346 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
347 'subject': ((('countryName', 'US'),),
348 (('stateOrProvinceName', 'California'),),
349 (('localityName', 'Mountain View'),),
350 (('organizationName', 'Google Inc'),)),
351 'subjectAltName': (('othername', 'blabla'),)}
352 fail(cert, 'google.com')
353
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000354 # Empty cert / no cert
355 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
356 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
357
Antoine Pitrou86d53ca2013-05-18 17:56:42 +0200358 # Issue #17980: avoid denials of service by refusing more than one
359 # wildcard per fragment.
360 cert = {'subject': ((('commonName', 'a*b.com'),),)}
361 ok(cert, 'axxb.com')
362 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
363 ok(cert, 'axxb.com')
364 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
365 with self.assertRaises(ssl.CertificateError) as cm:
366 ssl.match_hostname(cert, 'axxbxxc.com')
367 self.assertIn("too many wildcards", str(cm.exception))
368
Antoine Pitroud5323212010-10-22 18:19:07 +0000369 def test_server_side(self):
370 # server_hostname doesn't work for server sockets
371 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000372 with socket.socket() as sock:
373 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
374 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000375
Antoine Pitrou152efa22010-05-16 18:19:27 +0000376class ContextTests(unittest.TestCase):
377
Antoine Pitrou23df4832010-08-04 17:14:06 +0000378 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000379 def test_constructor(self):
Victor Stinner17ca3232011-05-10 00:48:41 +0200380 if hasattr(ssl, 'PROTOCOL_SSLv2'):
381 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000382 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
383 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
384 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
385 self.assertRaises(TypeError, ssl.SSLContext)
386 self.assertRaises(ValueError, ssl.SSLContext, -1)
387 self.assertRaises(ValueError, ssl.SSLContext, 42)
388
Antoine Pitrou23df4832010-08-04 17:14:06 +0000389 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000390 def test_protocol(self):
391 for proto in PROTOCOLS:
392 ctx = ssl.SSLContext(proto)
393 self.assertEqual(ctx.protocol, proto)
394
395 def test_ciphers(self):
396 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
397 ctx.set_ciphers("ALL")
398 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000399 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000400 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000401
Antoine Pitrou23df4832010-08-04 17:14:06 +0000402 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000403 def test_options(self):
404 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
405 # OP_ALL is the default value
406 self.assertEqual(ssl.OP_ALL, ctx.options)
407 ctx.options |= ssl.OP_NO_SSLv2
408 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
409 ctx.options)
410 ctx.options |= ssl.OP_NO_SSLv3
411 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
412 ctx.options)
413 if can_clear_options():
414 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
415 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
416 ctx.options)
417 ctx.options = 0
418 self.assertEqual(0, ctx.options)
419 else:
420 with self.assertRaises(ValueError):
421 ctx.options = 0
422
Antoine Pitrou152efa22010-05-16 18:19:27 +0000423 def test_verify(self):
424 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
425 # Default value
426 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
427 ctx.verify_mode = ssl.CERT_OPTIONAL
428 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
429 ctx.verify_mode = ssl.CERT_REQUIRED
430 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
431 ctx.verify_mode = ssl.CERT_NONE
432 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
433 with self.assertRaises(TypeError):
434 ctx.verify_mode = None
435 with self.assertRaises(ValueError):
436 ctx.verify_mode = 42
437
438 def test_load_cert_chain(self):
439 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
440 # Combined key and cert in a single file
441 ctx.load_cert_chain(CERTFILE)
442 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
443 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000444 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000445 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000446 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000447 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000448 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000449 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000450 ctx.load_cert_chain(EMPTYCERT)
451 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000452 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000453 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
454 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
455 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000456 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000457 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000458 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000459 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000460 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000461 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
462 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000463 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000464 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000465 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000466
467 def test_load_verify_locations(self):
468 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
469 ctx.load_verify_locations(CERTFILE)
470 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
471 ctx.load_verify_locations(BYTES_CERTFILE)
472 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
473 self.assertRaises(TypeError, ctx.load_verify_locations)
474 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000475 with self.assertRaises(IOError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000476 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000477 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000478 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000479 ctx.load_verify_locations(BADCERT)
480 ctx.load_verify_locations(CERTFILE, CAPATH)
481 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
482
Victor Stinner80f75e62011-01-29 11:31:20 +0000483 # Issue #10989: crash if the second argument type is invalid
484 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
485
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000486 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000487 def test_session_stats(self):
488 for proto in PROTOCOLS:
489 ctx = ssl.SSLContext(proto)
490 self.assertEqual(ctx.session_stats(), {
491 'number': 0,
492 'connect': 0,
493 'connect_good': 0,
494 'connect_renegotiate': 0,
495 'accept': 0,
496 'accept_good': 0,
497 'accept_renegotiate': 0,
498 'hits': 0,
499 'misses': 0,
500 'timeouts': 0,
501 'cache_full': 0,
502 })
503
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000504 def test_set_default_verify_paths(self):
505 # There's not much we can do to test that it acts as expected,
506 # so just check it doesn't crash or raise an exception.
507 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
508 ctx.set_default_verify_paths()
509
Antoine Pitrou152efa22010-05-16 18:19:27 +0000510
Bill Janssen6e027db2007-11-15 22:23:56 +0000511class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000512
Antoine Pitrou480a1242010-04-28 21:37:09 +0000513 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000514 with support.transient_internet("svn.python.org"):
515 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
516 cert_reqs=ssl.CERT_NONE)
517 try:
518 s.connect(("svn.python.org", 443))
519 self.assertEqual({}, s.getpeercert())
520 finally:
521 s.close()
522
523 # this should fail because we have no verification certs
524 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
525 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000526 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
527 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000528 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000529
Antoine Pitrou350c7222010-09-09 13:31:46 +0000530 # this should succeed because we specify the root cert
531 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
532 cert_reqs=ssl.CERT_REQUIRED,
533 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
534 try:
535 s.connect(("svn.python.org", 443))
536 self.assertTrue(s.getpeercert())
537 finally:
538 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000539
Antoine Pitrou86cbfec2011-02-26 23:25:34 +0000540 def test_connect_ex(self):
541 # Issue #11326: check connect_ex() implementation
542 with support.transient_internet("svn.python.org"):
543 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
544 cert_reqs=ssl.CERT_REQUIRED,
545 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
546 try:
547 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
548 self.assertTrue(s.getpeercert())
549 finally:
550 s.close()
551
552 def test_non_blocking_connect_ex(self):
553 # Issue #11326: non-blocking connect_ex() should allow handshake
554 # to proceed after the socket gets ready.
555 with support.transient_internet("svn.python.org"):
556 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
557 cert_reqs=ssl.CERT_REQUIRED,
558 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
559 do_handshake_on_connect=False)
560 try:
561 s.setblocking(False)
562 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitroud1c98452011-02-27 15:45:16 +0000563 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
564 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitrou86cbfec2011-02-26 23:25:34 +0000565 # Wait for connect to finish
566 select.select([], [s], [], 5.0)
567 # Non-blocking handshake
568 while True:
569 try:
570 s.do_handshake()
571 break
572 except ssl.SSLError as err:
573 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
574 select.select([s], [], [], 5.0)
575 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
576 select.select([], [s], [], 5.0)
577 else:
578 raise
579 # SSL established
580 self.assertTrue(s.getpeercert())
581 finally:
582 s.close()
583
Antoine Pitroub4410db2011-05-18 18:51:06 +0200584 def test_timeout_connect_ex(self):
585 # Issue #12065: on a timeout, connect_ex() should return the original
586 # errno (mimicking the behaviour of non-SSL sockets).
587 with support.transient_internet("svn.python.org"):
588 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
589 cert_reqs=ssl.CERT_REQUIRED,
590 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
591 do_handshake_on_connect=False)
592 try:
593 s.settimeout(0.0000001)
594 rc = s.connect_ex(('svn.python.org', 443))
595 if rc == 0:
596 self.skipTest("svn.python.org responded too quickly")
597 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
598 finally:
599 s.close()
600
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100601 def test_connect_ex_error(self):
Antoine Pitrouddb87ab2012-12-28 19:07:43 +0100602 with support.transient_internet("svn.python.org"):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100603 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
604 cert_reqs=ssl.CERT_REQUIRED,
605 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
606 try:
607 self.assertEqual(errno.ECONNREFUSED,
608 s.connect_ex(("svn.python.org", 444)))
609 finally:
610 s.close()
611
Antoine Pitrou152efa22010-05-16 18:19:27 +0000612 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000613 with support.transient_internet("svn.python.org"):
614 # Same as test_connect, but with a separately created context
615 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
616 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
617 s.connect(("svn.python.org", 443))
618 try:
619 self.assertEqual({}, s.getpeercert())
620 finally:
621 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000622 # Same with a server hostname
623 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
624 server_hostname="svn.python.org")
625 if ssl.HAS_SNI:
626 s.connect(("svn.python.org", 443))
627 s.close()
628 else:
629 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000630 # This should fail because we have no verification certs
631 ctx.verify_mode = ssl.CERT_REQUIRED
632 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000633 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000634 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000635 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000636 # This should succeed because we specify the root cert
637 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
638 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
639 s.connect(("svn.python.org", 443))
640 try:
641 cert = s.getpeercert()
642 self.assertTrue(cert)
643 finally:
644 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000645
646 def test_connect_capath(self):
647 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000648 # NOTE: the subject hashing algorithm has been changed between
649 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
650 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000651 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000652 with support.transient_internet("svn.python.org"):
653 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
654 ctx.verify_mode = ssl.CERT_REQUIRED
655 ctx.load_verify_locations(capath=CAPATH)
656 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
657 s.connect(("svn.python.org", 443))
658 try:
659 cert = s.getpeercert()
660 self.assertTrue(cert)
661 finally:
662 s.close()
663 # Same with a bytes `capath` argument
664 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
665 ctx.verify_mode = ssl.CERT_REQUIRED
666 ctx.load_verify_locations(capath=BYTES_CAPATH)
667 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
668 s.connect(("svn.python.org", 443))
669 try:
670 cert = s.getpeercert()
671 self.assertTrue(cert)
672 finally:
673 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000674
Antoine Pitroue3220242010-04-24 11:13:53 +0000675 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
676 def test_makefile_close(self):
677 # Issue #5238: creating a file-like object with makefile() shouldn't
678 # delay closing the underlying "real socket" (here tested with its
679 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000680 with support.transient_internet("svn.python.org"):
681 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
682 ss.connect(("svn.python.org", 443))
683 fd = ss.fileno()
684 f = ss.makefile()
685 f.close()
686 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000687 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000688 # Closing the SSL socket should close the fd too
689 ss.close()
690 gc.collect()
691 with self.assertRaises(OSError) as e:
692 os.read(fd, 0)
693 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000694
Antoine Pitrou480a1242010-04-28 21:37:09 +0000695 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000696 with support.transient_internet("svn.python.org"):
697 s = socket.socket(socket.AF_INET)
698 s.connect(("svn.python.org", 443))
699 s.setblocking(False)
700 s = ssl.wrap_socket(s,
701 cert_reqs=ssl.CERT_NONE,
702 do_handshake_on_connect=False)
703 count = 0
704 while True:
705 try:
706 count += 1
707 s.do_handshake()
708 break
709 except ssl.SSLError as err:
710 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
711 select.select([s], [], [])
712 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
713 select.select([], [s], [])
714 else:
715 raise
716 s.close()
717 if support.verbose:
718 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000719
Antoine Pitrou480a1242010-04-28 21:37:09 +0000720 def test_get_server_certificate(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000721 with support.transient_internet("svn.python.org"):
Benjamin Petersoncf25c5c2014-03-12 18:05:53 -0500722 pem = ssl.get_server_certificate(("svn.python.org", 443),
723 ssl.PROTOCOL_SSLv23)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000724 if not pem:
725 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen54cc54c2007-12-14 22:08:56 +0000726
Antoine Pitrou350c7222010-09-09 13:31:46 +0000727 try:
Benjamin Petersoncf25c5c2014-03-12 18:05:53 -0500728 pem = ssl.get_server_certificate(("svn.python.org", 443),
729 ssl.PROTOCOL_SSLv23,
730 ca_certs=CERTFILE)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000731 except ssl.SSLError as x:
732 #should fail
733 if support.verbose:
734 sys.stdout.write("%s\n" % x)
735 else:
736 self.fail("Got server certificate %s for svn.python.org!" % pem)
737
Benjamin Petersoncf25c5c2014-03-12 18:05:53 -0500738 pem = ssl.get_server_certificate(("svn.python.org", 443),
739 ssl.PROTOCOL_SSLv23,
740 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000741 if not pem:
742 self.fail("No server certificate on svn.python.org:443!")
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000743 if support.verbose:
Antoine Pitrou350c7222010-09-09 13:31:46 +0000744 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000745
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000746 def test_ciphers(self):
747 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000748 with support.transient_internet(remote[0]):
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000749 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
Antoine Pitrou350c7222010-09-09 13:31:46 +0000750 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000751 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000752 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
753 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
754 s.connect(remote)
755 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +0000756 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +0000757 with socket.socket(socket.AF_INET) as sock:
758 s = ssl.wrap_socket(sock,
759 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
760 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000761
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000762 def test_algorithms(self):
763 # Issue #8484: all algorithms should be available when verifying a
764 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +0000765 # SHA256 was added in OpenSSL 0.9.8
766 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
767 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrou16f6f832012-05-04 16:26:02 +0200768 # sha256.tbs-internet.com needs SNI to use the correct certificate
769 if not ssl.HAS_SNI:
770 self.skipTest("SNI needed for this test")
Victor Stinnerf332abb2011-01-08 03:16:05 +0000771 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
772 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000773 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +0000774 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrou16f6f832012-05-04 16:26:02 +0200775 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
776 ctx.verify_mode = ssl.CERT_REQUIRED
777 ctx.load_verify_locations(sha256_cert)
778 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
779 server_hostname="sha256.tbs-internet.com")
Antoine Pitroufec12ff2010-04-21 19:46:23 +0000780 try:
781 s.connect(remote)
782 if support.verbose:
783 sys.stdout.write("\nCipher with %r is %r\n" %
784 (remote, s.cipher()))
785 sys.stdout.write("Certificate is:\n%s\n" %
786 pprint.pformat(s.getpeercert()))
787 finally:
788 s.close()
789
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000790
791try:
792 import threading
793except ImportError:
794 _have_threads = False
795else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000796 _have_threads = True
797
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000798 from test.ssl_servers import make_https_server
799
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000800 class ThreadedEchoServer(threading.Thread):
801
802 class ConnectionHandler(threading.Thread):
803
804 """A mildly complicated class, because we want it to work both
805 with and without the SSL wrapper around the socket connection, so
806 that we can test the STARTTLS functionality."""
807
Bill Janssen6e027db2007-11-15 22:23:56 +0000808 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000809 self.server = server
810 self.running = False
811 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +0000812 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000813 self.sock.setblocking(1)
814 self.sslconn = None
815 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000816 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000817
Antoine Pitrou480a1242010-04-28 21:37:09 +0000818 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000819 try:
Antoine Pitroub5218772010-05-21 09:56:06 +0000820 self.sslconn = self.server.context.wrap_socket(
821 self.sock, server_side=True)
Nadeem Vawda7b39b9b2013-03-03 22:31:21 +0100822 except (ssl.SSLError, socket.error) as e:
823 # Treat ECONNRESET as though it were an SSLError - OpenSSL
824 # on Ubuntu abruptly closes the connection when asked to use
825 # an unsupported protocol.
826 if (not isinstance(e, ssl.SSLError) and
827 e.errno != errno.ECONNRESET):
828 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000829 # XXX Various errors can have happened here, for example
830 # a mismatching protocol version, an invalid certificate,
831 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100832 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000833 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +0000834 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000835 self.running = False
836 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000837 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000838 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000839 else:
Antoine Pitroub5218772010-05-21 09:56:06 +0000840 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000841 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000842 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000843 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
844 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000845 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000846 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
847 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000848 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000849 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
850 return True
851
852 def read(self):
853 if self.sslconn:
854 return self.sslconn.read()
855 else:
856 return self.sock.recv(1024)
857
858 def write(self, bytes):
859 if self.sslconn:
860 return self.sslconn.write(bytes)
861 else:
862 return self.sock.send(bytes)
863
864 def close(self):
865 if self.sslconn:
866 self.sslconn.close()
867 else:
868 self.sock.close()
869
Antoine Pitrou480a1242010-04-28 21:37:09 +0000870 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000871 self.running = True
872 if not self.server.starttls_server:
873 if not self.wrap_conn():
874 return
875 while self.running:
876 try:
877 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000878 stripped = msg.strip()
879 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000880 # eof, so quit this handler
881 self.running = False
882 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +0000883 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000884 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000885 sys.stdout.write(" server: client closed connection\n")
886 self.close()
887 return
Bill Janssen6e027db2007-11-15 22:23:56 +0000888 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +0000889 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000890 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000891 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000892 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000893 if not self.wrap_conn():
894 return
Bill Janssen40a0f662008-08-12 16:56:25 +0000895 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +0000896 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +0000897 if support.verbose and self.server.connectionchatty:
898 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +0000899 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +0000900 self.sock = self.sslconn.unwrap()
901 self.sslconn = None
902 if support.verbose and self.server.connectionchatty:
903 sys.stdout.write(" server: connection is now unencrypted...\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000904 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000905 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000906 self.server.connectionchatty):
907 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +0000908 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
909 % (msg, ctype, msg.lower(), ctype))
910 self.write(msg.lower())
Bill Janssen6e027db2007-11-15 22:23:56 +0000911 except socket.error:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000912 if self.server.chatty:
913 handle_error("Test server failure:\n")
914 self.close()
915 self.running = False
916 # normally, we'd just stop here, but for the test
917 # harness, we want to stop the server
918 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000919
Antoine Pitroub5218772010-05-21 09:56:06 +0000920 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000921 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +0000922 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroub5218772010-05-21 09:56:06 +0000923 ciphers=None, context=None):
924 if context:
925 self.context = context
926 else:
927 self.context = ssl.SSLContext(ssl_version
928 if ssl_version is not None
929 else ssl.PROTOCOL_TLSv1)
930 self.context.verify_mode = (certreqs if certreqs is not None
931 else ssl.CERT_NONE)
932 if cacerts:
933 self.context.load_verify_locations(cacerts)
934 if certificate:
935 self.context.load_cert_chain(certificate)
936 if ciphers:
937 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000938 self.chatty = chatty
939 self.connectionchatty = connectionchatty
940 self.starttls_server = starttls_server
941 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000942 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000943 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000944 self.active = False
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100945 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000946 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +0000947 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000948
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +0100949 def __enter__(self):
950 self.start(threading.Event())
951 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +0100952 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +0100953
954 def __exit__(self, *args):
955 self.stop()
956 self.join()
957
Antoine Pitrou480a1242010-04-28 21:37:09 +0000958 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000959 self.flag = flag
960 threading.Thread.start(self)
961
Antoine Pitrou480a1242010-04-28 21:37:09 +0000962 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +0000963 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000964 self.sock.listen(5)
965 self.active = True
966 if self.flag:
967 # signal an event
968 self.flag.set()
969 while self.active:
970 try:
971 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000972 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000973 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +0000974 + repr(connaddr) + '\n')
975 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000976 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +0100977 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000978 except socket.timeout:
979 pass
980 except KeyboardInterrupt:
981 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +0000982 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000983
Antoine Pitrou480a1242010-04-28 21:37:09 +0000984 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000985 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000986
Bill Janssen54cc54c2007-12-14 22:08:56 +0000987 class AsyncoreEchoServer(threading.Thread):
988
989 # this one's based on asyncore.dispatcher
990
991 class EchoServer (asyncore.dispatcher):
992
993 class ConnectionHandler (asyncore.dispatcher_with_send):
994
995 def __init__(self, conn, certfile):
996 self.socket = ssl.wrap_socket(conn, server_side=True,
997 certfile=certfile,
998 do_handshake_on_connect=False)
999 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001000 self._ssl_accepting = True
1001 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001002
1003 def readable(self):
1004 if isinstance(self.socket, ssl.SSLSocket):
1005 while self.socket.pending() > 0:
1006 self.handle_read_event()
1007 return True
1008
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001009 def _do_ssl_handshake(self):
1010 try:
1011 self.socket.do_handshake()
1012 except ssl.SSLError as err:
1013 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
1014 ssl.SSL_ERROR_WANT_WRITE):
1015 return
1016 elif err.args[0] == ssl.SSL_ERROR_EOF:
1017 return self.handle_close()
1018 raise
1019 except socket.error as err:
1020 if err.args[0] == errno.ECONNABORTED:
1021 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001022 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001023 self._ssl_accepting = False
1024
1025 def handle_read(self):
1026 if self._ssl_accepting:
1027 self._do_ssl_handshake()
1028 else:
1029 data = self.recv(1024)
1030 if support.verbose:
1031 sys.stdout.write(" server: read %s from client\n" % repr(data))
1032 if not data:
1033 self.close()
1034 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001035 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00001036
1037 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00001038 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001039 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001040 sys.stdout.write(" server: closed connection %s\n" % self.socket)
1041
1042 def handle_error(self):
1043 raise
1044
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001045 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001046 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001047 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1048 self.port = support.bind_port(sock, '')
1049 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001050 self.listen(5)
1051
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00001052 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001053 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001054 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
1055 self.ConnectionHandler(sock_obj, self.certfile)
1056
1057 def handle_error(self):
1058 raise
1059
Trent Nelson78520002008-04-10 20:54:35 +00001060 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001061 self.flag = None
1062 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001063 self.server = self.EchoServer(certfile)
1064 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00001065 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001066 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00001067
1068 def __str__(self):
1069 return "<%s %s>" % (self.__class__.__name__, self.server)
1070
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001071 def __enter__(self):
1072 self.start(threading.Event())
1073 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001074 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001075
1076 def __exit__(self, *args):
1077 if support.verbose:
1078 sys.stdout.write(" cleanup: stopping server.\n")
1079 self.stop()
1080 if support.verbose:
1081 sys.stdout.write(" cleanup: joining server thread.\n")
1082 self.join()
1083 if support.verbose:
1084 sys.stdout.write(" cleanup: successfully joined.\n")
1085
Bill Janssen54cc54c2007-12-14 22:08:56 +00001086 def start (self, flag=None):
1087 self.flag = flag
1088 threading.Thread.start(self)
1089
Antoine Pitrou480a1242010-04-28 21:37:09 +00001090 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001091 self.active = True
1092 if self.flag:
1093 self.flag.set()
1094 while self.active:
1095 try:
1096 asyncore.loop(1)
1097 except:
1098 pass
1099
Antoine Pitrou480a1242010-04-28 21:37:09 +00001100 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001101 self.active = False
1102 self.server.close()
1103
Antoine Pitrou480a1242010-04-28 21:37:09 +00001104 def bad_cert_test(certfile):
1105 """
1106 Launch a server with CERT_REQUIRED, and check that trying to
1107 connect to it with the given client certificate fails.
1108 """
Trent Nelson78520002008-04-10 20:54:35 +00001109 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001110 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +00001111 cacerts=CERTFILE, chatty=False,
1112 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001113 with server:
Thomas Woutersed03b412007-08-28 21:37:11 +00001114 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001115 with socket.socket() as sock:
1116 s = ssl.wrap_socket(sock,
1117 certfile=certfile,
1118 ssl_version=ssl.PROTOCOL_TLSv1)
1119 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001120 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001121 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001122 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Antoine Pitrou05830aa2010-04-27 13:15:18 +00001123 except socket.error as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001124 if support.verbose:
Georg Brandlb75b6392010-10-24 14:20:22 +00001125 sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001126 except IOError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001127 if x.errno != errno.ENOENT:
1128 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001129 if support.verbose:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001130 sys.stdout.write("\IOError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001131 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001132 raise AssertionError("Use of invalid cert should have failed!")
Thomas Woutersed03b412007-08-28 21:37:11 +00001133
Antoine Pitroub5218772010-05-21 09:56:06 +00001134 def server_params_test(client_context, server_context, indata=b"FOO\n",
1135 chatty=True, connectionchatty=False):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001136 """
1137 Launch a server, connect a client to it and try various reads
1138 and writes.
1139 """
Antoine Pitroub5218772010-05-21 09:56:06 +00001140 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001141 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001142 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001143 with server:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001144 with client_context.wrap_socket(socket.socket()) as s:
1145 s.connect((HOST, server.port))
1146 for arg in [indata, bytearray(indata), memoryview(indata)]:
1147 if connectionchatty:
1148 if support.verbose:
1149 sys.stdout.write(
1150 " client: sending %r...\n" % indata)
1151 s.write(arg)
1152 outdata = s.read()
1153 if connectionchatty:
1154 if support.verbose:
1155 sys.stdout.write(" client: read %r\n" % outdata)
1156 if outdata != indata.lower():
1157 raise AssertionError(
1158 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1159 % (outdata[:20], len(outdata),
1160 indata[:20].lower(), len(indata)))
1161 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001162 if connectionchatty:
1163 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001164 sys.stdout.write(" client: closing connection.\n")
1165 s.close()
Thomas Woutersed03b412007-08-28 21:37:11 +00001166
Antoine Pitroub5218772010-05-21 09:56:06 +00001167 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1168 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001169 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001170 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001171 certtype = {
1172 ssl.CERT_NONE: "CERT_NONE",
1173 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1174 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1175 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001176 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001177 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001178 sys.stdout.write(formatstr %
1179 (ssl.get_protocol_name(client_protocol),
1180 ssl.get_protocol_name(server_protocol),
1181 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001182 client_context = ssl.SSLContext(client_protocol)
1183 client_context.options = ssl.OP_ALL | client_options
1184 server_context = ssl.SSLContext(server_protocol)
1185 server_context.options = ssl.OP_ALL | server_options
1186 for ctx in (client_context, server_context):
1187 ctx.verify_mode = certsreqs
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001188 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1189 # will send an SSLv3 hello (rather than SSLv2) starting from
1190 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitroub5218772010-05-21 09:56:06 +00001191 ctx.set_ciphers("ALL")
1192 ctx.load_cert_chain(CERTFILE)
1193 ctx.load_verify_locations(CERTFILE)
1194 try:
1195 server_params_test(client_context, server_context,
1196 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001197 # Protocol mismatch can result in either an SSLError, or a
1198 # "Connection reset by peer" error.
1199 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001200 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001201 raise
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001202 except socket.error as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001203 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001204 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001205 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001206 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001207 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001208 "Client protocol %s succeeded with server protocol %s!"
1209 % (ssl.get_protocol_name(client_protocol),
1210 ssl.get_protocol_name(server_protocol)))
1211
1212
Bill Janssen6e027db2007-11-15 22:23:56 +00001213 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001214
Antoine Pitrou23df4832010-08-04 17:14:06 +00001215 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001216 def test_echo(self):
1217 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001218 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001219 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001220 for protocol in PROTOCOLS:
1221 context = ssl.SSLContext(protocol)
1222 context.load_cert_chain(CERTFILE)
1223 server_params_test(context, context,
1224 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001225
Antoine Pitrou480a1242010-04-28 21:37:09 +00001226 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001227 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001228 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001229 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1230 context.verify_mode = ssl.CERT_REQUIRED
1231 context.load_verify_locations(CERTFILE)
1232 context.load_cert_chain(CERTFILE)
1233 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001234 with server:
Antoine Pitroub5218772010-05-21 09:56:06 +00001235 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001236 s.connect((HOST, server.port))
1237 cert = s.getpeercert()
1238 self.assertTrue(cert, "Can't get peer certificate.")
1239 cipher = s.cipher()
1240 if support.verbose:
1241 sys.stdout.write(pprint.pformat(cert) + '\n')
1242 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1243 if 'subject' not in cert:
1244 self.fail("No subject field in certificate: %s." %
1245 pprint.pformat(cert))
1246 if ((('organizationName', 'Python Software Foundation'),)
1247 not in cert['subject']):
1248 self.fail(
1249 "Missing or invalid 'organizationName' field in certificate subject; "
1250 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001251 self.assertIn('notBefore', cert)
1252 self.assertIn('notAfter', cert)
1253 before = ssl.cert_time_to_seconds(cert['notBefore'])
1254 after = ssl.cert_time_to_seconds(cert['notAfter'])
1255 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001256 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001257
Antoine Pitrou480a1242010-04-28 21:37:09 +00001258 def test_empty_cert(self):
1259 """Connecting with an empty cert file"""
1260 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1261 "nullcert.pem"))
1262 def test_malformed_cert(self):
1263 """Connecting with a badly formatted certificate (syntax error)"""
1264 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1265 "badcert.pem"))
1266 def test_nonexisting_cert(self):
1267 """Connecting with a non-existing cert file"""
1268 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1269 "wrongcert.pem"))
1270 def test_malformed_key(self):
1271 """Connecting with a badly formatted key (syntax error)"""
1272 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1273 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001274
Antoine Pitrou480a1242010-04-28 21:37:09 +00001275 def test_rude_shutdown(self):
1276 """A brutal shutdown of an SSL server should raise an IOError
1277 in the client when attempting handshake.
1278 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001279 listener_ready = threading.Event()
1280 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001281
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001282 s = socket.socket()
1283 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001284
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001285 # `listener` runs in a thread. It sits in an accept() until
1286 # the main thread connects. Then it rudely closes the socket,
1287 # and sets Event `listener_gone` to let the main thread know
1288 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001289 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001290 s.listen(5)
1291 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001292 newsock, addr = s.accept()
1293 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001294 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001295 listener_gone.set()
1296
1297 def connector():
1298 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001299 with socket.socket() as c:
1300 c.connect((HOST, port))
1301 listener_gone.wait()
1302 try:
1303 ssl_sock = ssl.wrap_socket(c)
1304 except IOError:
1305 pass
1306 else:
1307 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001308
1309 t = threading.Thread(target=listener)
1310 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001311 try:
1312 connector()
1313 finally:
1314 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001315
Antoine Pitrou23df4832010-08-04 17:14:06 +00001316 @skip_if_broken_ubuntu_ssl
Victor Stinneree18b6f2011-05-10 00:38:00 +02001317 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'), "need SSLv2")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001318 def test_protocol_sslv2(self):
1319 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001320 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001321 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001322 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1323 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1324 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1325 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1326 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1327 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001328 # SSLv23 client with specific SSL options
1329 if no_sslv2_implies_sslv3_hello():
1330 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1331 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1332 client_options=ssl.OP_NO_SSLv2)
1333 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1334 client_options=ssl.OP_NO_SSLv3)
1335 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1336 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001337
Antoine Pitrou23df4832010-08-04 17:14:06 +00001338 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001339 def test_protocol_sslv23(self):
1340 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001341 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001342 sys.stdout.write("\n")
Victor Stinneree18b6f2011-05-10 00:38:00 +02001343 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1344 try:
1345 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
1346 except (ssl.SSLError, socket.error) as x:
1347 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1348 if support.verbose:
1349 sys.stdout.write(
1350 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1351 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001352 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1353 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1354 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001355
Antoine Pitrou480a1242010-04-28 21:37:09 +00001356 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1357 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1358 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001359
Antoine Pitrou480a1242010-04-28 21:37:09 +00001360 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1361 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1362 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001363
Antoine Pitroub5218772010-05-21 09:56:06 +00001364 # Server with specific SSL options
1365 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1366 server_options=ssl.OP_NO_SSLv3)
1367 # Will choose TLSv1
1368 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1369 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1370 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1371 server_options=ssl.OP_NO_TLSv1)
1372
1373
Antoine Pitrou23df4832010-08-04 17:14:06 +00001374 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001375 def test_protocol_sslv3(self):
1376 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001377 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001378 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001379 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1380 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1381 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinneree18b6f2011-05-10 00:38:00 +02001382 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1383 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04001384 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
1385 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001386 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001387 if no_sslv2_implies_sslv3_hello():
1388 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1389 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1390 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001391
Antoine Pitrou23df4832010-08-04 17:14:06 +00001392 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001393 def test_protocol_tlsv1(self):
1394 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001395 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001396 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001397 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1398 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1399 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinneree18b6f2011-05-10 00:38:00 +02001400 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1401 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001402 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04001403 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
1404 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001405
Antoine Pitrou480a1242010-04-28 21:37:09 +00001406 def test_starttls(self):
1407 """Switching from clear text to encrypted and back again."""
1408 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 +00001409
Trent Nelson78520002008-04-10 20:54:35 +00001410 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001411 ssl_version=ssl.PROTOCOL_TLSv1,
1412 starttls_server=True,
1413 chatty=True,
1414 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001415 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001416 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001417 s = socket.socket()
1418 s.setblocking(1)
1419 s.connect((HOST, server.port))
1420 if support.verbose:
1421 sys.stdout.write("\n")
1422 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001423 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001424 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001425 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001426 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001427 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001428 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001429 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001430 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001431 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001432 msg = outdata.strip().lower()
1433 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1434 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001435 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001436 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001437 " client: read %r from server, starting TLS...\n"
1438 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001439 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1440 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001441 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1442 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001443 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001444 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001445 " client: read %r from server, ending TLS...\n"
1446 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001447 s = conn.unwrap()
1448 wrapped = False
1449 else:
1450 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001451 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001452 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001453 if support.verbose:
1454 sys.stdout.write(" client: closing connection.\n")
1455 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001456 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001457 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001458 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001459 if wrapped:
1460 conn.close()
1461 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001462 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001463
Antoine Pitrou480a1242010-04-28 21:37:09 +00001464 def test_socketserver(self):
1465 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001466 server = make_https_server(self, CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001467 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001468 if support.verbose:
1469 sys.stdout.write('\n')
1470 with open(CERTFILE, 'rb') as f:
1471 d1 = f.read()
1472 d2 = ''
1473 # now fetch the same data from the HTTPS server
1474 url = 'https://%s:%d/%s' % (
1475 HOST, server.port, os.path.split(CERTFILE)[1])
1476 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001477 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001478 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001479 if dlen and (int(dlen) > 0):
1480 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001481 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001482 sys.stdout.write(
1483 " client: read %d bytes from remote server '%s'\n"
1484 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001485 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001486 f.close()
1487 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001488
Antoine Pitrou480a1242010-04-28 21:37:09 +00001489 def test_asyncore_server(self):
1490 """Check the example asyncore integration."""
1491 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001492
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001493 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001494 sys.stdout.write("\n")
1495
Antoine Pitrou480a1242010-04-28 21:37:09 +00001496 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001497 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001498 with server:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001499 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001500 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001501 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001502 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001503 " client: sending %r...\n" % indata)
1504 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001505 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001506 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001507 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001508 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001509 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001510 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1511 % (outdata[:20], len(outdata),
1512 indata[:20].lower(), len(indata)))
1513 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001514 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001515 sys.stdout.write(" client: closing connection.\n")
1516 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001517 if support.verbose:
1518 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001519
Antoine Pitrou480a1242010-04-28 21:37:09 +00001520 def test_recv_send(self):
1521 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001522 if support.verbose:
1523 sys.stdout.write("\n")
1524
1525 server = ThreadedEchoServer(CERTFILE,
1526 certreqs=ssl.CERT_NONE,
1527 ssl_version=ssl.PROTOCOL_TLSv1,
1528 cacerts=CERTFILE,
1529 chatty=True,
1530 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001531 with server:
1532 s = ssl.wrap_socket(socket.socket(),
1533 server_side=False,
1534 certfile=CERTFILE,
1535 ca_certs=CERTFILE,
1536 cert_reqs=ssl.CERT_NONE,
1537 ssl_version=ssl.PROTOCOL_TLSv1)
1538 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001539 # helper methods for standardising recv* method signatures
1540 def _recv_into():
1541 b = bytearray(b"\0"*100)
1542 count = s.recv_into(b)
1543 return b[:count]
1544
1545 def _recvfrom_into():
1546 b = bytearray(b"\0"*100)
1547 count, addr = s.recvfrom_into(b)
1548 return b[:count]
1549
1550 # (name, method, whether to expect success, *args)
1551 send_methods = [
1552 ('send', s.send, True, []),
1553 ('sendto', s.sendto, False, ["some.address"]),
1554 ('sendall', s.sendall, True, []),
1555 ]
1556 recv_methods = [
1557 ('recv', s.recv, True, []),
1558 ('recvfrom', s.recvfrom, False, ["some.address"]),
1559 ('recv_into', _recv_into, True, []),
1560 ('recvfrom_into', _recvfrom_into, False, []),
1561 ]
1562 data_prefix = "PREFIX_"
1563
1564 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001565 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001566 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001567 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001568 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001569 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001570 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001571 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001572 "<<{outdata:r}>> ({nout:d}) received; "
1573 "expected <<{indata:r}>> ({nin:d})\n".format(
1574 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001575 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001576 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001577 )
1578 )
1579 except ValueError as e:
1580 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001581 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001582 "Failed to send with method <<{name:s}>>; "
1583 "expected to succeed.\n".format(name=meth_name)
1584 )
1585 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001586 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001587 "Method <<{name:s}>> failed with unexpected "
1588 "exception message: {exp:s}\n".format(
1589 name=meth_name, exp=e
1590 )
1591 )
1592
1593 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001594 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001595 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001596 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001597 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001598 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001599 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001600 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001601 "<<{outdata:r}>> ({nout:d}) received; "
1602 "expected <<{indata:r}>> ({nin:d})\n".format(
1603 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001604 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001605 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001606 )
1607 )
1608 except ValueError as e:
1609 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001610 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001611 "Failed to receive with method <<{name:s}>>; "
1612 "expected to succeed.\n".format(name=meth_name)
1613 )
1614 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001615 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001616 "Method <<{name:s}>> failed with unexpected "
1617 "exception message: {exp:s}\n".format(
1618 name=meth_name, exp=e
1619 )
1620 )
1621 # consume data
1622 s.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001623 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001624 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001625
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001626 def test_handshake_timeout(self):
1627 # Issue #5103: SSL handshake must respect the socket timeout
1628 server = socket.socket(socket.AF_INET)
1629 host = "127.0.0.1"
1630 port = support.bind_port(server)
1631 started = threading.Event()
1632 finish = False
1633
1634 def serve():
1635 server.listen(5)
1636 started.set()
1637 conns = []
1638 while not finish:
1639 r, w, e = select.select([server], [], [], 0.1)
1640 if server in r:
1641 # Let the socket hang around rather than having
1642 # it closed by garbage collection.
1643 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001644 for sock in conns:
1645 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001646
1647 t = threading.Thread(target=serve)
1648 t.start()
1649 started.wait()
1650
1651 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001652 try:
1653 c = socket.socket(socket.AF_INET)
1654 c.settimeout(0.2)
1655 c.connect((host, port))
1656 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001657 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001658 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001659 finally:
1660 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001661 try:
1662 c = socket.socket(socket.AF_INET)
1663 c = ssl.wrap_socket(c)
1664 c.settimeout(0.2)
1665 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001666 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001667 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001668 finally:
1669 c.close()
1670 finally:
1671 finish = True
1672 t.join()
1673 server.close()
1674
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01001675 def test_server_accept(self):
1676 # Issue #16357: accept() on a SSLSocket created through
1677 # SSLContext.wrap_socket().
1678 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1679 context.verify_mode = ssl.CERT_REQUIRED
1680 context.load_verify_locations(CERTFILE)
1681 context.load_cert_chain(CERTFILE)
1682 server = socket.socket(socket.AF_INET)
1683 host = "127.0.0.1"
1684 port = support.bind_port(server)
1685 server = context.wrap_socket(server, server_side=True)
1686
1687 evt = threading.Event()
1688 remote = None
1689 peer = None
1690 def serve():
1691 nonlocal remote, peer
1692 server.listen(5)
1693 # Block on the accept and wait on the connection to close.
1694 evt.set()
1695 remote, peer = server.accept()
1696 remote.recv(1)
1697
1698 t = threading.Thread(target=serve)
1699 t.start()
1700 # Client wait until server setup and perform a connect.
1701 evt.wait()
1702 client = context.wrap_socket(socket.socket())
1703 client.connect((host, port))
1704 client_addr = client.getsockname()
1705 client.close()
1706 t.join()
1707 # Sanity checks.
1708 self.assertIsInstance(remote, ssl.SSLSocket)
1709 self.assertEqual(peer, client_addr)
1710
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001711 def test_default_ciphers(self):
1712 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1713 try:
1714 # Force a set of weak ciphers on our client context
1715 context.set_ciphers("DES")
1716 except ssl.SSLError:
1717 self.skipTest("no DES cipher available")
1718 with ThreadedEchoServer(CERTFILE,
1719 ssl_version=ssl.PROTOCOL_SSLv23,
1720 chatty=False) as server:
1721 with socket.socket() as sock:
1722 s = context.wrap_socket(sock)
1723 with self.assertRaises((OSError, ssl.SSLError)):
1724 s.connect((HOST, server.port))
1725 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1726
Bill Janssen58afe4c2008-09-08 16:45:19 +00001727
Thomas Woutersed03b412007-08-28 21:37:11 +00001728def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00001729 if support.verbose:
1730 plats = {
1731 'Linux': platform.linux_distribution,
1732 'Mac': platform.mac_ver,
1733 'Windows': platform.win32_ver,
1734 }
1735 for name, func in plats.items():
1736 plat = func()
1737 if plat and plat[0]:
1738 plat = '%s %r' % (name, plat)
1739 break
1740 else:
1741 plat = repr(platform.platform())
1742 print("test_ssl: testing with %r %r" %
1743 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1744 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00001745 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou15cee622010-08-04 16:45:21 +00001746
Antoine Pitrou152efa22010-05-16 18:19:27 +00001747 for filename in [
1748 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1749 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1750 BADCERT, BADKEY, EMPTYCERT]:
1751 if not os.path.exists(filename):
1752 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001753
Antoine Pitrou152efa22010-05-16 18:19:27 +00001754 tests = [ContextTests, BasicSocketTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00001755
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001756 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001757 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001758
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001759 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001760 thread_info = support.threading_setup()
1761 if thread_info and support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00001762 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00001763
Antoine Pitrou480a1242010-04-28 21:37:09 +00001764 try:
1765 support.run_unittest(*tests)
1766 finally:
1767 if _have_threads:
1768 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00001769
1770if __name__ == "__main__":
1771 test_main()