blob: 210040b4f07801ad9aad5a362ca448c11330c9f7 [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
Christian Heimes9424bb42013-06-17 15:32:57 +02009import datetime
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000010import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000011import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000012import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000013import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000014import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000015import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000016import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000017import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000018import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000019import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000020import functools
Antoine Pitrou242db722013-05-01 20:52:07 +020021from unittest import mock
Thomas Woutersed03b412007-08-28 21:37:11 +000022
Antoine Pitrou05d936d2010-10-13 11:38:36 +000023ssl = support.import_module("ssl")
24
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010025PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000026HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000027
28data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000029
Antoine Pitrou81564092010-10-08 23:06:24 +000030# The custom key and certificate files used in test_ssl are generated
31# using Lib/test/make_ssl_certs.py.
32# Other certificates are simply fetched from the Internet servers they
33# are meant to authenticate.
34
Antoine Pitrou152efa22010-05-16 18:19:27 +000035CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000036BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000037ONLYCERT = data_file("ssl_cert.pem")
38ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000039BYTES_ONLYCERT = os.fsencode(ONLYCERT)
40BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +020041CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
42ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
43KEY_PASSWORD = "somepass"
Antoine Pitrou152efa22010-05-16 18:19:27 +000044CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000045BYTES_CAPATH = os.fsencode(CAPATH)
Antoine Pitrou152efa22010-05-16 18:19:27 +000046
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010047# Two keys and certs signed by the same CA (for SNI tests)
48SIGNED_CERTFILE = data_file("keycert3.pem")
49SIGNED_CERTFILE2 = data_file("keycert4.pem")
50SIGNING_CA = data_file("pycacert.pem")
51
Antoine Pitrou152efa22010-05-16 18:19:27 +000052SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
53
54EMPTYCERT = data_file("nullcert.pem")
55BADCERT = data_file("badcert.pem")
56WRONGCERT = data_file("XXXnonexisting.pem")
57BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020058NOKIACERT = data_file("nokia.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000059
Antoine Pitrou0e576f12011-12-22 10:03:38 +010060DHFILE = data_file("dh512.pem")
61BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000062
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010063
Thomas Woutersed03b412007-08-28 21:37:11 +000064def handle_error(prefix):
65 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000066 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000067 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000068
Antoine Pitroub5218772010-05-21 09:56:06 +000069def can_clear_options():
70 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020071 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000072
73def no_sslv2_implies_sslv3_hello():
74 # 0.9.7h or higher
75 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
76
Christian Heimes9424bb42013-06-17 15:32:57 +020077def asn1time(cert_time):
78 # Some versions of OpenSSL ignore seconds, see #18207
79 # 0.9.8.i
80 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
81 fmt = "%b %d %H:%M:%S %Y GMT"
82 dt = datetime.datetime.strptime(cert_time, fmt)
83 dt = dt.replace(second=0)
84 cert_time = dt.strftime(fmt)
85 # %d adds leading zero but ASN1_TIME_print() uses leading space
86 if cert_time[4] == "0":
87 cert_time = cert_time[:4] + " " + cert_time[5:]
88
89 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +000090
Antoine Pitrou23df4832010-08-04 17:14:06 +000091# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
92def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +020093 if hasattr(ssl, 'PROTOCOL_SSLv2'):
94 @functools.wraps(func)
95 def f(*args, **kwargs):
96 try:
97 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
98 except ssl.SSLError:
99 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
100 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
101 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
102 return func(*args, **kwargs)
103 return f
104 else:
105 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000106
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100107needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
108
Antoine Pitrou23df4832010-08-04 17:14:06 +0000109
Antoine Pitrou152efa22010-05-16 18:19:27 +0000110class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000111
Antoine Pitrou480a1242010-04-28 21:37:09 +0000112 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000113 ssl.CERT_NONE
114 ssl.CERT_OPTIONAL
115 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100116 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100117 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100118 if ssl.HAS_ECDH:
119 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100120 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
121 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000122 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100123 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000124
Antoine Pitrou480a1242010-04-28 21:37:09 +0000125 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000126 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000127 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000128 sys.stdout.write("\n RAND_status is %d (%s)\n"
129 % (v, (v and "sufficient randomness") or
130 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200131
132 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
133 self.assertEqual(len(data), 16)
134 self.assertEqual(is_cryptographic, v == 1)
135 if v:
136 data = ssl.RAND_bytes(16)
137 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200138 else:
139 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200140
Jesus Ceac8754a12012-09-11 02:00:58 +0200141 self.assertRaises(TypeError, ssl.RAND_egd, 1)
142 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000143 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000144
Antoine Pitrou480a1242010-04-28 21:37:09 +0000145 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000146 # note that this uses an 'unofficial' function in _ssl.c,
147 # provided solely for this test, to exercise the certificate
148 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000149 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000150 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000151 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200152 self.assertEqual(p['issuer'],
153 ((('countryName', 'XY'),),
154 (('localityName', 'Castle Anthrax'),),
155 (('organizationName', 'Python Software Foundation'),),
156 (('commonName', 'localhost'),))
157 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100158 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200159 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
160 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200161 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
162 self.assertEqual(p['subject'],
163 ((('countryName', 'XY'),),
164 (('localityName', 'Castle Anthrax'),),
165 (('organizationName', 'Python Software Foundation'),),
166 (('commonName', 'localhost'),))
167 )
168 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
169 # Issue #13034: the subjectAltName in some certificates
170 # (notably projects.developer.nokia.com:443) wasn't parsed
171 p = ssl._ssl._test_decode_cert(NOKIACERT)
172 if support.verbose:
173 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
174 self.assertEqual(p['subjectAltName'],
175 (('DNS', 'projects.developer.nokia.com'),
176 ('DNS', 'projects.forum.nokia.com'))
177 )
Thomas Woutersed03b412007-08-28 21:37:11 +0000178
Antoine Pitrou480a1242010-04-28 21:37:09 +0000179 def test_DER_to_PEM(self):
180 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
181 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000182 d1 = ssl.PEM_cert_to_DER_cert(pem)
183 p2 = ssl.DER_cert_to_PEM_cert(d1)
184 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000185 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000186 if not p2.startswith(ssl.PEM_HEADER + '\n'):
187 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
188 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
189 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000190
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000191 def test_openssl_version(self):
192 n = ssl.OPENSSL_VERSION_NUMBER
193 t = ssl.OPENSSL_VERSION_INFO
194 s = ssl.OPENSSL_VERSION
195 self.assertIsInstance(n, int)
196 self.assertIsInstance(t, tuple)
197 self.assertIsInstance(s, str)
198 # Some sanity checks follow
199 # >= 0.9
200 self.assertGreaterEqual(n, 0x900000)
201 # < 2.0
202 self.assertLess(n, 0x20000000)
203 major, minor, fix, patch, status = t
204 self.assertGreaterEqual(major, 0)
205 self.assertLess(major, 2)
206 self.assertGreaterEqual(minor, 0)
207 self.assertLess(minor, 256)
208 self.assertGreaterEqual(fix, 0)
209 self.assertLess(fix, 256)
210 self.assertGreaterEqual(patch, 0)
211 self.assertLessEqual(patch, 26)
212 self.assertGreaterEqual(status, 0)
213 self.assertLessEqual(status, 15)
214 # Version string as returned by OpenSSL, the format might change
215 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
216 (s, t))
217
Antoine Pitrou9d543662010-04-23 23:10:32 +0000218 @support.cpython_only
219 def test_refcycle(self):
220 # Issue #7943: an SSL object doesn't create reference cycles with
221 # itself.
222 s = socket.socket(socket.AF_INET)
223 ss = ssl.wrap_socket(s)
224 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100225 with support.check_warnings(("", ResourceWarning)):
226 del ss
227 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000228
Antoine Pitroua468adc2010-09-14 14:43:44 +0000229 def test_wrapped_unconnected(self):
230 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200231 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000232 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100233 with ssl.wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100234 self.assertRaises(OSError, ss.recv, 1)
235 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
236 self.assertRaises(OSError, ss.recvfrom, 1)
237 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
238 self.assertRaises(OSError, ss.send, b'x')
239 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000240
Antoine Pitrou40f08742010-04-24 22:04:40 +0000241 def test_timeout(self):
242 # Issue #8524: when creating an SSL socket, the timeout of the
243 # original socket should be retained.
244 for timeout in (None, 0.0, 5.0):
245 s = socket.socket(socket.AF_INET)
246 s.settimeout(timeout)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100247 with ssl.wrap_socket(s) as ss:
248 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000249
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000250 def test_errors(self):
251 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000252 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000253 "certfile must be specified",
254 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000255 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000256 "certfile must be specified for server-side operations",
257 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000258 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000259 "certfile must be specified for server-side operations",
260 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100261 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
262 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
263 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200264 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000265 with socket.socket() as sock:
266 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000267 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200268 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000269 with socket.socket() as sock:
270 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000271 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200272 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000273 with socket.socket() as sock:
274 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000275 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000276
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000277 def test_match_hostname(self):
278 def ok(cert, hostname):
279 ssl.match_hostname(cert, hostname)
280 def fail(cert, hostname):
281 self.assertRaises(ssl.CertificateError,
282 ssl.match_hostname, cert, hostname)
283
284 cert = {'subject': ((('commonName', 'example.com'),),)}
285 ok(cert, 'example.com')
286 ok(cert, 'ExAmple.cOm')
287 fail(cert, 'www.example.com')
288 fail(cert, '.example.com')
289 fail(cert, 'example.org')
290 fail(cert, 'exampleXcom')
291
292 cert = {'subject': ((('commonName', '*.a.com'),),)}
293 ok(cert, 'foo.a.com')
294 fail(cert, 'bar.foo.a.com')
295 fail(cert, 'a.com')
296 fail(cert, 'Xa.com')
297 fail(cert, '.a.com')
298
299 cert = {'subject': ((('commonName', 'a.*.com'),),)}
300 ok(cert, 'a.foo.com')
301 fail(cert, 'a..com')
302 fail(cert, 'a.com')
303
304 cert = {'subject': ((('commonName', 'f*.com'),),)}
305 ok(cert, 'foo.com')
306 ok(cert, 'f.com')
307 fail(cert, 'bar.com')
308 fail(cert, 'foo.a.com')
309 fail(cert, 'bar.foo.com')
310
311 # Slightly fake real-world example
312 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
313 'subject': ((('commonName', 'linuxfrz.org'),),),
314 'subjectAltName': (('DNS', 'linuxfr.org'),
315 ('DNS', 'linuxfr.com'),
316 ('othername', '<unsupported>'))}
317 ok(cert, 'linuxfr.org')
318 ok(cert, 'linuxfr.com')
319 # Not a "DNS" entry
320 fail(cert, '<unsupported>')
321 # When there is a subjectAltName, commonName isn't used
322 fail(cert, 'linuxfrz.org')
323
324 # A pristine real-world example
325 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
326 'subject': ((('countryName', 'US'),),
327 (('stateOrProvinceName', 'California'),),
328 (('localityName', 'Mountain View'),),
329 (('organizationName', 'Google Inc'),),
330 (('commonName', 'mail.google.com'),))}
331 ok(cert, 'mail.google.com')
332 fail(cert, 'gmail.com')
333 # Only commonName is considered
334 fail(cert, 'California')
335
336 # Neither commonName nor subjectAltName
337 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
338 'subject': ((('countryName', 'US'),),
339 (('stateOrProvinceName', 'California'),),
340 (('localityName', 'Mountain View'),),
341 (('organizationName', 'Google Inc'),))}
342 fail(cert, 'mail.google.com')
343
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200344 # No DNS entry in subjectAltName but a commonName
345 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
346 'subject': ((('countryName', 'US'),),
347 (('stateOrProvinceName', 'California'),),
348 (('localityName', 'Mountain View'),),
349 (('commonName', 'mail.google.com'),)),
350 'subjectAltName': (('othername', 'blabla'), )}
351 ok(cert, 'mail.google.com')
352
353 # No DNS entry subjectAltName and no commonName
354 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
355 'subject': ((('countryName', 'US'),),
356 (('stateOrProvinceName', 'California'),),
357 (('localityName', 'Mountain View'),),
358 (('organizationName', 'Google Inc'),)),
359 'subjectAltName': (('othername', 'blabla'),)}
360 fail(cert, 'google.com')
361
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000362 # Empty cert / no cert
363 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
364 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
365
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200366 # Issue #17980: avoid denials of service by refusing more than one
367 # wildcard per fragment.
368 cert = {'subject': ((('commonName', 'a*b.com'),),)}
369 ok(cert, 'axxb.com')
370 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
371 ok(cert, 'axxb.com')
372 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
373 with self.assertRaises(ssl.CertificateError) as cm:
374 ssl.match_hostname(cert, 'axxbxxc.com')
375 self.assertIn("too many wildcards", str(cm.exception))
376
Antoine Pitroud5323212010-10-22 18:19:07 +0000377 def test_server_side(self):
378 # server_hostname doesn't work for server sockets
379 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000380 with socket.socket() as sock:
381 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
382 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000383
Antoine Pitroud6494802011-07-21 01:11:30 +0200384 def test_unknown_channel_binding(self):
385 # should raise ValueError for unknown type
386 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100387 with ssl.wrap_socket(s) as ss:
388 with self.assertRaises(ValueError):
389 ss.get_channel_binding("unknown-type")
Antoine Pitroud6494802011-07-21 01:11:30 +0200390
391 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
392 "'tls-unique' channel binding not available")
393 def test_tls_unique_channel_binding(self):
394 # unconnected should return None for known type
395 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100396 with ssl.wrap_socket(s) as ss:
397 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200398 # the same for server-side
399 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100400 with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
401 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200402
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600403 def test_dealloc_warn(self):
404 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
405 r = repr(ss)
406 with self.assertWarns(ResourceWarning) as cm:
407 ss = None
408 support.gc_collect()
409 self.assertIn(r, str(cm.warning.args[0]))
410
Christian Heimes6d7ad132013-06-09 18:02:55 +0200411 def test_get_default_verify_paths(self):
412 paths = ssl.get_default_verify_paths()
413 self.assertEqual(len(paths), 6)
414 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
415
416 with support.EnvironmentVarGuard() as env:
417 env["SSL_CERT_DIR"] = CAPATH
418 env["SSL_CERT_FILE"] = CERTFILE
419 paths = ssl.get_default_verify_paths()
420 self.assertEqual(paths.cafile, CERTFILE)
421 self.assertEqual(paths.capath, CAPATH)
422
423
Christian Heimes46bebee2013-06-09 19:03:31 +0200424 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
425 def test_enum_cert_store(self):
426 self.assertEqual(ssl.X509_ASN_ENCODING, 1)
427 self.assertEqual(ssl.PKCS_7_ASN_ENCODING, 0x00010000)
428
429 self.assertEqual(ssl.enum_cert_store("CA"),
430 ssl.enum_cert_store("CA", "certificate"))
431 ssl.enum_cert_store("CA", "crl")
432 self.assertEqual(ssl.enum_cert_store("ROOT"),
433 ssl.enum_cert_store("ROOT", "certificate"))
434 ssl.enum_cert_store("ROOT", "crl")
435
436 self.assertRaises(TypeError, ssl.enum_cert_store)
437 self.assertRaises(WindowsError, ssl.enum_cert_store, "")
438 self.assertRaises(ValueError, ssl.enum_cert_store, "CA", "wrong")
439
440 ca = ssl.enum_cert_store("CA")
441 self.assertIsInstance(ca, list)
442 self.assertIsInstance(ca[0], tuple)
443 self.assertEqual(len(ca[0]), 2)
444 self.assertIsInstance(ca[0][0], bytes)
445 self.assertIsInstance(ca[0][1], int)
446
Antoine Pitrou152efa22010-05-16 18:19:27 +0000447class ContextTests(unittest.TestCase):
448
Antoine Pitrou23df4832010-08-04 17:14:06 +0000449 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000450 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100451 for protocol in PROTOCOLS:
452 ssl.SSLContext(protocol)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000453 self.assertRaises(TypeError, ssl.SSLContext)
454 self.assertRaises(ValueError, ssl.SSLContext, -1)
455 self.assertRaises(ValueError, ssl.SSLContext, 42)
456
Antoine Pitrou23df4832010-08-04 17:14:06 +0000457 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000458 def test_protocol(self):
459 for proto in PROTOCOLS:
460 ctx = ssl.SSLContext(proto)
461 self.assertEqual(ctx.protocol, proto)
462
463 def test_ciphers(self):
464 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
465 ctx.set_ciphers("ALL")
466 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000467 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000468 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000469
Antoine Pitrou23df4832010-08-04 17:14:06 +0000470 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000471 def test_options(self):
472 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
473 # OP_ALL is the default value
474 self.assertEqual(ssl.OP_ALL, ctx.options)
475 ctx.options |= ssl.OP_NO_SSLv2
476 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
477 ctx.options)
478 ctx.options |= ssl.OP_NO_SSLv3
479 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
480 ctx.options)
481 if can_clear_options():
482 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
483 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
484 ctx.options)
485 ctx.options = 0
486 self.assertEqual(0, ctx.options)
487 else:
488 with self.assertRaises(ValueError):
489 ctx.options = 0
490
Antoine Pitrou152efa22010-05-16 18:19:27 +0000491 def test_verify(self):
492 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
493 # Default value
494 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
495 ctx.verify_mode = ssl.CERT_OPTIONAL
496 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
497 ctx.verify_mode = ssl.CERT_REQUIRED
498 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
499 ctx.verify_mode = ssl.CERT_NONE
500 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
501 with self.assertRaises(TypeError):
502 ctx.verify_mode = None
503 with self.assertRaises(ValueError):
504 ctx.verify_mode = 42
505
506 def test_load_cert_chain(self):
507 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
508 # Combined key and cert in a single file
509 ctx.load_cert_chain(CERTFILE)
510 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
511 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200512 with self.assertRaises(OSError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000513 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000514 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000515 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000516 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000517 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000518 ctx.load_cert_chain(EMPTYCERT)
519 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000520 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000521 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
522 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
523 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000524 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000525 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000526 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000527 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000528 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000529 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
530 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000531 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000532 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000533 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200534 # Password protected key and cert
535 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
536 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
537 ctx.load_cert_chain(CERTFILE_PROTECTED,
538 password=bytearray(KEY_PASSWORD.encode()))
539 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
540 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
541 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
542 bytearray(KEY_PASSWORD.encode()))
543 with self.assertRaisesRegex(TypeError, "should be a string"):
544 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
545 with self.assertRaises(ssl.SSLError):
546 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
547 with self.assertRaisesRegex(ValueError, "cannot be longer"):
548 # openssl has a fixed limit on the password buffer.
549 # PEM_BUFSIZE is generally set to 1kb.
550 # Return a string larger than this.
551 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
552 # Password callback
553 def getpass_unicode():
554 return KEY_PASSWORD
555 def getpass_bytes():
556 return KEY_PASSWORD.encode()
557 def getpass_bytearray():
558 return bytearray(KEY_PASSWORD.encode())
559 def getpass_badpass():
560 return "badpass"
561 def getpass_huge():
562 return b'a' * (1024 * 1024)
563 def getpass_bad_type():
564 return 9
565 def getpass_exception():
566 raise Exception('getpass error')
567 class GetPassCallable:
568 def __call__(self):
569 return KEY_PASSWORD
570 def getpass(self):
571 return KEY_PASSWORD
572 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
573 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
574 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
575 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
576 ctx.load_cert_chain(CERTFILE_PROTECTED,
577 password=GetPassCallable().getpass)
578 with self.assertRaises(ssl.SSLError):
579 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
580 with self.assertRaisesRegex(ValueError, "cannot be longer"):
581 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
582 with self.assertRaisesRegex(TypeError, "must return a string"):
583 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
584 with self.assertRaisesRegex(Exception, "getpass error"):
585 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
586 # Make sure the password function isn't called if it isn't needed
587 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000588
589 def test_load_verify_locations(self):
590 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
591 ctx.load_verify_locations(CERTFILE)
592 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
593 ctx.load_verify_locations(BYTES_CERTFILE)
594 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
595 self.assertRaises(TypeError, ctx.load_verify_locations)
596 self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200597 with self.assertRaises(OSError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000598 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000599 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000600 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000601 ctx.load_verify_locations(BADCERT)
602 ctx.load_verify_locations(CERTFILE, CAPATH)
603 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
604
Victor Stinner80f75e62011-01-29 11:31:20 +0000605 # Issue #10989: crash if the second argument type is invalid
606 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
607
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100608 def test_load_dh_params(self):
609 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
610 ctx.load_dh_params(DHFILE)
611 if os.name != 'nt':
612 ctx.load_dh_params(BYTES_DHFILE)
613 self.assertRaises(TypeError, ctx.load_dh_params)
614 self.assertRaises(TypeError, ctx.load_dh_params, None)
615 with self.assertRaises(FileNotFoundError) as cm:
616 ctx.load_dh_params(WRONGCERT)
617 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +0200618 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100619 ctx.load_dh_params(CERTFILE)
620
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000621 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000622 def test_session_stats(self):
623 for proto in PROTOCOLS:
624 ctx = ssl.SSLContext(proto)
625 self.assertEqual(ctx.session_stats(), {
626 'number': 0,
627 'connect': 0,
628 'connect_good': 0,
629 'connect_renegotiate': 0,
630 'accept': 0,
631 'accept_good': 0,
632 'accept_renegotiate': 0,
633 'hits': 0,
634 'misses': 0,
635 'timeouts': 0,
636 'cache_full': 0,
637 })
638
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000639 def test_set_default_verify_paths(self):
640 # There's not much we can do to test that it acts as expected,
641 # so just check it doesn't crash or raise an exception.
642 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
643 ctx.set_default_verify_paths()
644
Antoine Pitrou501da612011-12-21 09:27:41 +0100645 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +0100646 def test_set_ecdh_curve(self):
647 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
648 ctx.set_ecdh_curve("prime256v1")
649 ctx.set_ecdh_curve(b"prime256v1")
650 self.assertRaises(TypeError, ctx.set_ecdh_curve)
651 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
652 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
653 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
654
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100655 @needs_sni
656 def test_sni_callback(self):
657 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
658
659 # set_servername_callback expects a callable, or None
660 self.assertRaises(TypeError, ctx.set_servername_callback)
661 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
662 self.assertRaises(TypeError, ctx.set_servername_callback, "")
663 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
664
665 def dummycallback(sock, servername, ctx):
666 pass
667 ctx.set_servername_callback(None)
668 ctx.set_servername_callback(dummycallback)
669
670 @needs_sni
671 def test_sni_callback_refcycle(self):
672 # Reference cycles through the servername callback are detected
673 # and cleared.
674 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
675 def dummycallback(sock, servername, ctx, cycle=ctx):
676 pass
677 ctx.set_servername_callback(dummycallback)
678 wr = weakref.ref(ctx)
679 del ctx, dummycallback
680 gc.collect()
681 self.assertIs(wr(), None)
682
Christian Heimes9a5395a2013-06-17 15:44:12 +0200683 def test_cert_store_stats(self):
684 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
685 self.assertEqual(ctx.cert_store_stats(),
686 {'x509_ca': 0, 'crl': 0, 'x509': 0})
687 ctx.load_cert_chain(CERTFILE)
688 self.assertEqual(ctx.cert_store_stats(),
689 {'x509_ca': 0, 'crl': 0, 'x509': 0})
690 ctx.load_verify_locations(CERTFILE)
691 self.assertEqual(ctx.cert_store_stats(),
692 {'x509_ca': 0, 'crl': 0, 'x509': 1})
693 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
694 self.assertEqual(ctx.cert_store_stats(),
695 {'x509_ca': 1, 'crl': 0, 'x509': 2})
696
697 def test_get_ca_certs(self):
698 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
699 self.assertEqual(ctx.get_ca_certs(), [])
700 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
701 ctx.load_verify_locations(CERTFILE)
702 self.assertEqual(ctx.get_ca_certs(), [])
703 # but SVN_PYTHON_ORG_ROOT_CERT is a CA cert
704 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
705 self.assertEqual(ctx.get_ca_certs(),
706 [{'issuer': ((('organizationName', 'Root CA'),),
707 (('organizationalUnitName', 'http://www.cacert.org'),),
708 (('commonName', 'CA Cert Signing Authority'),),
709 (('emailAddress', 'support@cacert.org'),)),
710 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
711 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
712 'serialNumber': '00',
713 'subject': ((('organizationName', 'Root CA'),),
714 (('organizationalUnitName', 'http://www.cacert.org'),),
715 (('commonName', 'CA Cert Signing Authority'),),
716 (('emailAddress', 'support@cacert.org'),)),
717 'version': 3}])
718
719 with open(SVN_PYTHON_ORG_ROOT_CERT) as f:
720 pem = f.read()
721 der = ssl.PEM_cert_to_DER_cert(pem)
722 self.assertEqual(ctx.get_ca_certs(True), [der])
723
Antoine Pitrou152efa22010-05-16 18:19:27 +0000724
Antoine Pitrou3b36fb12012-06-22 21:11:52 +0200725class SSLErrorTests(unittest.TestCase):
726
727 def test_str(self):
728 # The str() of a SSLError doesn't include the errno
729 e = ssl.SSLError(1, "foo")
730 self.assertEqual(str(e), "foo")
731 self.assertEqual(e.errno, 1)
732 # Same for a subclass
733 e = ssl.SSLZeroReturnError(1, "foo")
734 self.assertEqual(str(e), "foo")
735 self.assertEqual(e.errno, 1)
736
737 def test_lib_reason(self):
738 # Test the library and reason attributes
739 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
740 with self.assertRaises(ssl.SSLError) as cm:
741 ctx.load_dh_params(CERTFILE)
742 self.assertEqual(cm.exception.library, 'PEM')
743 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
744 s = str(cm.exception)
745 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
746
747 def test_subclass(self):
748 # Check that the appropriate SSLError subclass is raised
749 # (this only tests one of them)
750 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
751 with socket.socket() as s:
752 s.bind(("127.0.0.1", 0))
753 s.listen(5)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100754 c = socket.socket()
755 c.connect(s.getsockname())
756 c.setblocking(False)
757 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +0200758 with self.assertRaises(ssl.SSLWantReadError) as cm:
759 c.do_handshake()
760 s = str(cm.exception)
761 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
762 # For compatibility
763 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
764
765
Bill Janssen6e027db2007-11-15 22:23:56 +0000766class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000767
Antoine Pitrou480a1242010-04-28 21:37:09 +0000768 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000769 with support.transient_internet("svn.python.org"):
770 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
771 cert_reqs=ssl.CERT_NONE)
772 try:
773 s.connect(("svn.python.org", 443))
774 self.assertEqual({}, s.getpeercert())
775 finally:
776 s.close()
777
778 # this should fail because we have no verification certs
779 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
780 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000781 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
782 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000783 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000784
Antoine Pitrou350c7222010-09-09 13:31:46 +0000785 # this should succeed because we specify the root cert
786 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
787 cert_reqs=ssl.CERT_REQUIRED,
788 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
789 try:
790 s.connect(("svn.python.org", 443))
791 self.assertTrue(s.getpeercert())
792 finally:
793 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000794
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000795 def test_connect_ex(self):
796 # Issue #11326: check connect_ex() implementation
797 with support.transient_internet("svn.python.org"):
798 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
799 cert_reqs=ssl.CERT_REQUIRED,
800 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
801 try:
802 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
803 self.assertTrue(s.getpeercert())
804 finally:
805 s.close()
806
807 def test_non_blocking_connect_ex(self):
808 # Issue #11326: non-blocking connect_ex() should allow handshake
809 # to proceed after the socket gets ready.
810 with support.transient_internet("svn.python.org"):
811 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
812 cert_reqs=ssl.CERT_REQUIRED,
813 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
814 do_handshake_on_connect=False)
815 try:
816 s.setblocking(False)
817 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +0000818 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
819 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000820 # Wait for connect to finish
821 select.select([], [s], [], 5.0)
822 # Non-blocking handshake
823 while True:
824 try:
825 s.do_handshake()
826 break
Antoine Pitrou41032a62011-10-27 23:56:55 +0200827 except ssl.SSLWantReadError:
828 select.select([s], [], [], 5.0)
829 except ssl.SSLWantWriteError:
830 select.select([], [s], [], 5.0)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +0000831 # SSL established
832 self.assertTrue(s.getpeercert())
833 finally:
834 s.close()
835
Antoine Pitroub4410db2011-05-18 18:51:06 +0200836 def test_timeout_connect_ex(self):
837 # Issue #12065: on a timeout, connect_ex() should return the original
838 # errno (mimicking the behaviour of non-SSL sockets).
839 with support.transient_internet("svn.python.org"):
840 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
841 cert_reqs=ssl.CERT_REQUIRED,
842 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
843 do_handshake_on_connect=False)
844 try:
845 s.settimeout(0.0000001)
846 rc = s.connect_ex(('svn.python.org', 443))
847 if rc == 0:
848 self.skipTest("svn.python.org responded too quickly")
849 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
850 finally:
851 s.close()
852
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100853 def test_connect_ex_error(self):
Antoine Pitrouddb87ab2012-12-28 19:07:43 +0100854 with support.transient_internet("svn.python.org"):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100855 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
856 cert_reqs=ssl.CERT_REQUIRED,
857 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
858 try:
859 self.assertEqual(errno.ECONNREFUSED,
860 s.connect_ex(("svn.python.org", 444)))
861 finally:
862 s.close()
863
Antoine Pitrou152efa22010-05-16 18:19:27 +0000864 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000865 with support.transient_internet("svn.python.org"):
866 # Same as test_connect, but with a separately created context
867 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
868 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
869 s.connect(("svn.python.org", 443))
870 try:
871 self.assertEqual({}, s.getpeercert())
872 finally:
873 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +0000874 # Same with a server hostname
875 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
876 server_hostname="svn.python.org")
877 if ssl.HAS_SNI:
878 s.connect(("svn.python.org", 443))
879 s.close()
880 else:
881 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000882 # This should fail because we have no verification certs
883 ctx.verify_mode = ssl.CERT_REQUIRED
884 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +0000885 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +0000886 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +0000887 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +0000888 # This should succeed because we specify the root cert
889 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
890 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
891 s.connect(("svn.python.org", 443))
892 try:
893 cert = s.getpeercert()
894 self.assertTrue(cert)
895 finally:
896 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +0000897
898 def test_connect_capath(self):
899 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +0000900 # NOTE: the subject hashing algorithm has been changed between
901 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
902 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +0000903 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +0000904 with support.transient_internet("svn.python.org"):
905 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
906 ctx.verify_mode = ssl.CERT_REQUIRED
907 ctx.load_verify_locations(capath=CAPATH)
908 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
909 s.connect(("svn.python.org", 443))
910 try:
911 cert = s.getpeercert()
912 self.assertTrue(cert)
913 finally:
914 s.close()
915 # Same with a bytes `capath` argument
916 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
917 ctx.verify_mode = ssl.CERT_REQUIRED
918 ctx.load_verify_locations(capath=BYTES_CAPATH)
919 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
920 s.connect(("svn.python.org", 443))
921 try:
922 cert = s.getpeercert()
923 self.assertTrue(cert)
924 finally:
925 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000926
Antoine Pitroue3220242010-04-24 11:13:53 +0000927 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
928 def test_makefile_close(self):
929 # Issue #5238: creating a file-like object with makefile() shouldn't
930 # delay closing the underlying "real socket" (here tested with its
931 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +0000932 with support.transient_internet("svn.python.org"):
933 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
934 ss.connect(("svn.python.org", 443))
935 fd = ss.fileno()
936 f = ss.makefile()
937 f.close()
938 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +0000939 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000940 # Closing the SSL socket should close the fd too
941 ss.close()
942 gc.collect()
943 with self.assertRaises(OSError) as e:
944 os.read(fd, 0)
945 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +0000946
Antoine Pitrou480a1242010-04-28 21:37:09 +0000947 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +0000948 with support.transient_internet("svn.python.org"):
949 s = socket.socket(socket.AF_INET)
950 s.connect(("svn.python.org", 443))
951 s.setblocking(False)
952 s = ssl.wrap_socket(s,
953 cert_reqs=ssl.CERT_NONE,
954 do_handshake_on_connect=False)
955 count = 0
956 while True:
957 try:
958 count += 1
959 s.do_handshake()
960 break
Antoine Pitrou41032a62011-10-27 23:56:55 +0200961 except ssl.SSLWantReadError:
962 select.select([s], [], [])
963 except ssl.SSLWantWriteError:
964 select.select([], [s], [])
Antoine Pitrou350c7222010-09-09 13:31:46 +0000965 s.close()
966 if support.verbose:
967 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000968
Antoine Pitrou480a1242010-04-28 21:37:09 +0000969 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +0200970 def _test_get_server_certificate(host, port, cert=None):
971 with support.transient_internet(host):
972 pem = ssl.get_server_certificate((host, port))
973 if not pem:
974 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200975
Antoine Pitrou15399c32011-04-28 19:23:55 +0200976 try:
977 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
978 except ssl.SSLError as x:
979 #should fail
980 if support.verbose:
981 sys.stdout.write("%s\n" % x)
982 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200983 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
984
Antoine Pitrou15399c32011-04-28 19:23:55 +0200985 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
986 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200987 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000988 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +0200989 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +0000990
Antoine Pitrou15399c32011-04-28 19:23:55 +0200991 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
992 if support.IPV6_ENABLED:
993 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +0000994
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +0000995 def test_ciphers(self):
996 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +0000997 with support.transient_internet(remote[0]):
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100998 with ssl.wrap_socket(socket.socket(socket.AF_INET),
999 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1000 s.connect(remote)
1001 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1002 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1003 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001004 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +00001005 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +00001006 with socket.socket(socket.AF_INET) as sock:
1007 s = ssl.wrap_socket(sock,
1008 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1009 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001010
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001011 def test_algorithms(self):
1012 # Issue #8484: all algorithms should be available when verifying a
1013 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +00001014 # SHA256 was added in OpenSSL 0.9.8
1015 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1016 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001017 # sha256.tbs-internet.com needs SNI to use the correct certificate
1018 if not ssl.HAS_SNI:
1019 self.skipTest("SNI needed for this test")
Victor Stinnerf332abb2011-01-08 03:16:05 +00001020 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1021 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001022 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +00001023 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001024 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1025 ctx.verify_mode = ssl.CERT_REQUIRED
1026 ctx.load_verify_locations(sha256_cert)
1027 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1028 server_hostname="sha256.tbs-internet.com")
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001029 try:
1030 s.connect(remote)
1031 if support.verbose:
1032 sys.stdout.write("\nCipher with %r is %r\n" %
1033 (remote, s.cipher()))
1034 sys.stdout.write("Certificate is:\n%s\n" %
1035 pprint.pformat(s.getpeercert()))
1036 finally:
1037 s.close()
1038
Christian Heimes9a5395a2013-06-17 15:44:12 +02001039 def test_get_ca_certs_capath(self):
1040 # capath certs are loaded on request
1041 with support.transient_internet("svn.python.org"):
1042 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1043 ctx.verify_mode = ssl.CERT_REQUIRED
1044 ctx.load_verify_locations(capath=CAPATH)
1045 self.assertEqual(ctx.get_ca_certs(), [])
1046 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1047 s.connect(("svn.python.org", 443))
1048 try:
1049 cert = s.getpeercert()
1050 self.assertTrue(cert)
1051 finally:
1052 s.close()
1053 self.assertEqual(len(ctx.get_ca_certs()), 1)
1054
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001055
1056try:
1057 import threading
1058except ImportError:
1059 _have_threads = False
1060else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001061 _have_threads = True
1062
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001063 from test.ssl_servers import make_https_server
1064
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001065 class ThreadedEchoServer(threading.Thread):
1066
1067 class ConnectionHandler(threading.Thread):
1068
1069 """A mildly complicated class, because we want it to work both
1070 with and without the SSL wrapper around the socket connection, so
1071 that we can test the STARTTLS functionality."""
1072
Bill Janssen6e027db2007-11-15 22:23:56 +00001073 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001074 self.server = server
1075 self.running = False
1076 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001077 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001078 self.sock.setblocking(1)
1079 self.sslconn = None
1080 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001081 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001082
Antoine Pitrou480a1242010-04-28 21:37:09 +00001083 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001084 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001085 self.sslconn = self.server.context.wrap_socket(
1086 self.sock, server_side=True)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001087 self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001088 except (ssl.SSLError, ConnectionResetError) as e:
1089 # We treat ConnectionResetError as though it were an
1090 # SSLError - OpenSSL on Ubuntu abruptly closes the
1091 # connection when asked to use an unsupported protocol.
1092 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001093 # XXX Various errors can have happened here, for example
1094 # a mismatching protocol version, an invalid certificate,
1095 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001096 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001097 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001098 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001099 self.running = False
1100 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001101 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001102 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001103 else:
Antoine Pitroub5218772010-05-21 09:56:06 +00001104 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001105 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001106 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001107 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1108 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001109 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001110 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1111 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001112 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001113 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001114 sys.stdout.write(" server: selected protocol is now "
1115 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001116 return True
1117
1118 def read(self):
1119 if self.sslconn:
1120 return self.sslconn.read()
1121 else:
1122 return self.sock.recv(1024)
1123
1124 def write(self, bytes):
1125 if self.sslconn:
1126 return self.sslconn.write(bytes)
1127 else:
1128 return self.sock.send(bytes)
1129
1130 def close(self):
1131 if self.sslconn:
1132 self.sslconn.close()
1133 else:
1134 self.sock.close()
1135
Antoine Pitrou480a1242010-04-28 21:37:09 +00001136 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001137 self.running = True
1138 if not self.server.starttls_server:
1139 if not self.wrap_conn():
1140 return
1141 while self.running:
1142 try:
1143 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001144 stripped = msg.strip()
1145 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001146 # eof, so quit this handler
1147 self.running = False
1148 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001149 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001150 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001151 sys.stdout.write(" server: client closed connection\n")
1152 self.close()
1153 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001154 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001155 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001156 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001157 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001158 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001159 if not self.wrap_conn():
1160 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001161 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001162 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001163 if support.verbose and self.server.connectionchatty:
1164 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001165 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001166 self.sock = self.sslconn.unwrap()
1167 self.sslconn = None
1168 if support.verbose and self.server.connectionchatty:
1169 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001170 elif stripped == b'CB tls-unique':
1171 if support.verbose and self.server.connectionchatty:
1172 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1173 data = self.sslconn.get_channel_binding("tls-unique")
1174 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001175 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001176 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001177 self.server.connectionchatty):
1178 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001179 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1180 % (msg, ctype, msg.lower(), ctype))
1181 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001182 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001183 if self.server.chatty:
1184 handle_error("Test server failure:\n")
1185 self.close()
1186 self.running = False
1187 # normally, we'd just stop here, but for the test
1188 # harness, we want to stop the server
1189 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001190
Antoine Pitroub5218772010-05-21 09:56:06 +00001191 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001192 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001193 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001194 npn_protocols=None, ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00001195 if context:
1196 self.context = context
1197 else:
1198 self.context = ssl.SSLContext(ssl_version
1199 if ssl_version is not None
1200 else ssl.PROTOCOL_TLSv1)
1201 self.context.verify_mode = (certreqs if certreqs is not None
1202 else ssl.CERT_NONE)
1203 if cacerts:
1204 self.context.load_verify_locations(cacerts)
1205 if certificate:
1206 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001207 if npn_protocols:
1208 self.context.set_npn_protocols(npn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00001209 if ciphers:
1210 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001211 self.chatty = chatty
1212 self.connectionchatty = connectionchatty
1213 self.starttls_server = starttls_server
1214 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001215 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001216 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001217 self.active = False
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001218 self.selected_protocols = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001219 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001220 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001221 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001222
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001223 def __enter__(self):
1224 self.start(threading.Event())
1225 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001226 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001227
1228 def __exit__(self, *args):
1229 self.stop()
1230 self.join()
1231
Antoine Pitrou480a1242010-04-28 21:37:09 +00001232 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001233 self.flag = flag
1234 threading.Thread.start(self)
1235
Antoine Pitrou480a1242010-04-28 21:37:09 +00001236 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00001237 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001238 self.sock.listen(5)
1239 self.active = True
1240 if self.flag:
1241 # signal an event
1242 self.flag.set()
1243 while self.active:
1244 try:
1245 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001246 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001247 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00001248 + repr(connaddr) + '\n')
1249 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001250 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01001251 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001252 except socket.timeout:
1253 pass
1254 except KeyboardInterrupt:
1255 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001256 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001257
Antoine Pitrou480a1242010-04-28 21:37:09 +00001258 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001259 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001260
Bill Janssen54cc54c2007-12-14 22:08:56 +00001261 class AsyncoreEchoServer(threading.Thread):
1262
1263 # this one's based on asyncore.dispatcher
1264
1265 class EchoServer (asyncore.dispatcher):
1266
1267 class ConnectionHandler (asyncore.dispatcher_with_send):
1268
1269 def __init__(self, conn, certfile):
1270 self.socket = ssl.wrap_socket(conn, server_side=True,
1271 certfile=certfile,
1272 do_handshake_on_connect=False)
1273 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001274 self._ssl_accepting = True
1275 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001276
1277 def readable(self):
1278 if isinstance(self.socket, ssl.SSLSocket):
1279 while self.socket.pending() > 0:
1280 self.handle_read_event()
1281 return True
1282
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001283 def _do_ssl_handshake(self):
1284 try:
1285 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02001286 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1287 return
1288 except ssl.SSLEOFError:
1289 return self.handle_close()
1290 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001291 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02001292 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001293 if err.args[0] == errno.ECONNABORTED:
1294 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001295 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001296 self._ssl_accepting = False
1297
1298 def handle_read(self):
1299 if self._ssl_accepting:
1300 self._do_ssl_handshake()
1301 else:
1302 data = self.recv(1024)
1303 if support.verbose:
1304 sys.stdout.write(" server: read %s from client\n" % repr(data))
1305 if not data:
1306 self.close()
1307 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001308 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00001309
1310 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00001311 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001312 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001313 sys.stdout.write(" server: closed connection %s\n" % self.socket)
1314
1315 def handle_error(self):
1316 raise
1317
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001318 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001319 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001320 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1321 self.port = support.bind_port(sock, '')
1322 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001323 self.listen(5)
1324
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00001325 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001326 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001327 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
1328 self.ConnectionHandler(sock_obj, self.certfile)
1329
1330 def handle_error(self):
1331 raise
1332
Trent Nelson78520002008-04-10 20:54:35 +00001333 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001334 self.flag = None
1335 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001336 self.server = self.EchoServer(certfile)
1337 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00001338 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001339 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00001340
1341 def __str__(self):
1342 return "<%s %s>" % (self.__class__.__name__, self.server)
1343
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001344 def __enter__(self):
1345 self.start(threading.Event())
1346 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001347 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001348
1349 def __exit__(self, *args):
1350 if support.verbose:
1351 sys.stdout.write(" cleanup: stopping server.\n")
1352 self.stop()
1353 if support.verbose:
1354 sys.stdout.write(" cleanup: joining server thread.\n")
1355 self.join()
1356 if support.verbose:
1357 sys.stdout.write(" cleanup: successfully joined.\n")
1358
Bill Janssen54cc54c2007-12-14 22:08:56 +00001359 def start (self, flag=None):
1360 self.flag = flag
1361 threading.Thread.start(self)
1362
Antoine Pitrou480a1242010-04-28 21:37:09 +00001363 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001364 self.active = True
1365 if self.flag:
1366 self.flag.set()
1367 while self.active:
1368 try:
1369 asyncore.loop(1)
1370 except:
1371 pass
1372
Antoine Pitrou480a1242010-04-28 21:37:09 +00001373 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001374 self.active = False
1375 self.server.close()
1376
Antoine Pitrou480a1242010-04-28 21:37:09 +00001377 def bad_cert_test(certfile):
1378 """
1379 Launch a server with CERT_REQUIRED, and check that trying to
1380 connect to it with the given client certificate fails.
1381 """
Trent Nelson78520002008-04-10 20:54:35 +00001382 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001383 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +00001384 cacerts=CERTFILE, chatty=False,
1385 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001386 with server:
Thomas Woutersed03b412007-08-28 21:37:11 +00001387 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001388 with socket.socket() as sock:
1389 s = ssl.wrap_socket(sock,
1390 certfile=certfile,
1391 ssl_version=ssl.PROTOCOL_TLSv1)
1392 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001393 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001394 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001395 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Andrew Svetlov0832af62012-12-18 23:10:48 +02001396 except OSError as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001397 if support.verbose:
Andrew Svetlov0832af62012-12-18 23:10:48 +02001398 sys.stdout.write("\nOSError is %s\n" % x.args[1])
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001399 except OSError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001400 if x.errno != errno.ENOENT:
1401 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001402 if support.verbose:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001403 sys.stdout.write("\OSError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001404 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001405 raise AssertionError("Use of invalid cert should have failed!")
Thomas Woutersed03b412007-08-28 21:37:11 +00001406
Antoine Pitroub5218772010-05-21 09:56:06 +00001407 def server_params_test(client_context, server_context, indata=b"FOO\n",
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001408 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001409 """
1410 Launch a server, connect a client to it and try various reads
1411 and writes.
1412 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001413 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00001414 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001415 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001416 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001417 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001418 with client_context.wrap_socket(socket.socket(),
1419 server_hostname=sni_name) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001420 s.connect((HOST, server.port))
1421 for arg in [indata, bytearray(indata), memoryview(indata)]:
1422 if connectionchatty:
1423 if support.verbose:
1424 sys.stdout.write(
1425 " client: sending %r...\n" % indata)
1426 s.write(arg)
1427 outdata = s.read()
1428 if connectionchatty:
1429 if support.verbose:
1430 sys.stdout.write(" client: read %r\n" % outdata)
1431 if outdata != indata.lower():
1432 raise AssertionError(
1433 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1434 % (outdata[:20], len(outdata),
1435 indata[:20].lower(), len(indata)))
1436 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001437 if connectionchatty:
1438 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001439 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001440 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01001441 'compression': s.compression(),
1442 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001443 'peercert': s.getpeercert(),
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001444 'client_npn_protocol': s.selected_npn_protocol()
1445 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01001446 s.close()
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001447 stats['server_npn_protocols'] = server.selected_protocols
1448 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00001449
Antoine Pitroub5218772010-05-21 09:56:06 +00001450 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1451 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001452 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001453 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001454 certtype = {
1455 ssl.CERT_NONE: "CERT_NONE",
1456 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1457 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1458 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001459 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001460 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001461 sys.stdout.write(formatstr %
1462 (ssl.get_protocol_name(client_protocol),
1463 ssl.get_protocol_name(server_protocol),
1464 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001465 client_context = ssl.SSLContext(client_protocol)
1466 client_context.options = ssl.OP_ALL | client_options
1467 server_context = ssl.SSLContext(server_protocol)
1468 server_context.options = ssl.OP_ALL | server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01001469
1470 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
1471 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
1472 # starting from OpenSSL 1.0.0 (see issue #8322).
1473 if client_context.protocol == ssl.PROTOCOL_SSLv23:
1474 client_context.set_ciphers("ALL")
1475
Antoine Pitroub5218772010-05-21 09:56:06 +00001476 for ctx in (client_context, server_context):
1477 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00001478 ctx.load_cert_chain(CERTFILE)
1479 ctx.load_verify_locations(CERTFILE)
1480 try:
1481 server_params_test(client_context, server_context,
1482 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001483 # Protocol mismatch can result in either an SSLError, or a
1484 # "Connection reset by peer" error.
1485 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001486 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001487 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02001488 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001489 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001490 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001491 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001492 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001493 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001494 "Client protocol %s succeeded with server protocol %s!"
1495 % (ssl.get_protocol_name(client_protocol),
1496 ssl.get_protocol_name(server_protocol)))
1497
1498
Bill Janssen6e027db2007-11-15 22:23:56 +00001499 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001500
Antoine Pitrou23df4832010-08-04 17:14:06 +00001501 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001502 def test_echo(self):
1503 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001504 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001505 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001506 for protocol in PROTOCOLS:
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01001507 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
1508 context = ssl.SSLContext(protocol)
1509 context.load_cert_chain(CERTFILE)
1510 server_params_test(context, context,
1511 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001512
Antoine Pitrou480a1242010-04-28 21:37:09 +00001513 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001514 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001515 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001516 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1517 context.verify_mode = ssl.CERT_REQUIRED
1518 context.load_verify_locations(CERTFILE)
1519 context.load_cert_chain(CERTFILE)
1520 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001521 with server:
Antoine Pitroub5218772010-05-21 09:56:06 +00001522 s = context.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001523 s.connect((HOST, server.port))
1524 cert = s.getpeercert()
1525 self.assertTrue(cert, "Can't get peer certificate.")
1526 cipher = s.cipher()
1527 if support.verbose:
1528 sys.stdout.write(pprint.pformat(cert) + '\n')
1529 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1530 if 'subject' not in cert:
1531 self.fail("No subject field in certificate: %s." %
1532 pprint.pformat(cert))
1533 if ((('organizationName', 'Python Software Foundation'),)
1534 not in cert['subject']):
1535 self.fail(
1536 "Missing or invalid 'organizationName' field in certificate subject; "
1537 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001538 self.assertIn('notBefore', cert)
1539 self.assertIn('notAfter', cert)
1540 before = ssl.cert_time_to_seconds(cert['notBefore'])
1541 after = ssl.cert_time_to_seconds(cert['notAfter'])
1542 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001543 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001544
Antoine Pitrou480a1242010-04-28 21:37:09 +00001545 def test_empty_cert(self):
1546 """Connecting with an empty cert file"""
1547 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1548 "nullcert.pem"))
1549 def test_malformed_cert(self):
1550 """Connecting with a badly formatted certificate (syntax error)"""
1551 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1552 "badcert.pem"))
1553 def test_nonexisting_cert(self):
1554 """Connecting with a non-existing cert file"""
1555 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1556 "wrongcert.pem"))
1557 def test_malformed_key(self):
1558 """Connecting with a badly formatted key (syntax error)"""
1559 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1560 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001561
Antoine Pitrou480a1242010-04-28 21:37:09 +00001562 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001563 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00001564 in the client when attempting handshake.
1565 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00001566 listener_ready = threading.Event()
1567 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001568
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001569 s = socket.socket()
1570 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001571
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001572 # `listener` runs in a thread. It sits in an accept() until
1573 # the main thread connects. Then it rudely closes the socket,
1574 # and sets Event `listener_gone` to let the main thread know
1575 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00001576 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00001577 s.listen(5)
1578 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001579 newsock, addr = s.accept()
1580 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001581 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001582 listener_gone.set()
1583
1584 def connector():
1585 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00001586 with socket.socket() as c:
1587 c.connect((HOST, port))
1588 listener_gone.wait()
1589 try:
1590 ssl_sock = ssl.wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001591 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001592 pass
1593 else:
1594 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00001595
1596 t = threading.Thread(target=listener)
1597 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001598 try:
1599 connector()
1600 finally:
1601 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00001602
Antoine Pitrou23df4832010-08-04 17:14:06 +00001603 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02001604 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
1605 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001606 def test_protocol_sslv2(self):
1607 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001608 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001609 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001610 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1611 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1612 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1613 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1614 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1615 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001616 # SSLv23 client with specific SSL options
1617 if no_sslv2_implies_sslv3_hello():
1618 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1619 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1620 client_options=ssl.OP_NO_SSLv2)
1621 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1622 client_options=ssl.OP_NO_SSLv3)
1623 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1624 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001625
Antoine Pitrou23df4832010-08-04 17:14:06 +00001626 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001627 def test_protocol_sslv23(self):
1628 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001629 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001630 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02001631 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1632 try:
1633 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02001634 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02001635 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1636 if support.verbose:
1637 sys.stdout.write(
1638 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1639 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00001640 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1641 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1642 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001643
Antoine Pitrou480a1242010-04-28 21:37:09 +00001644 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1645 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1646 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001647
Antoine Pitrou480a1242010-04-28 21:37:09 +00001648 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1649 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1650 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001651
Antoine Pitroub5218772010-05-21 09:56:06 +00001652 # Server with specific SSL options
1653 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1654 server_options=ssl.OP_NO_SSLv3)
1655 # Will choose TLSv1
1656 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1657 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1658 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1659 server_options=ssl.OP_NO_TLSv1)
1660
1661
Antoine Pitrou23df4832010-08-04 17:14:06 +00001662 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001663 def test_protocol_sslv3(self):
1664 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001665 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001666 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001667 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1668 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1669 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001670 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1671 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04001672 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
1673 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001674 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00001675 if no_sslv2_implies_sslv3_hello():
1676 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1677 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1678 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001679
Antoine Pitrou23df4832010-08-04 17:14:06 +00001680 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001681 def test_protocol_tlsv1(self):
1682 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001683 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001684 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001685 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1686 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1687 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02001688 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1689 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001690 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04001691 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
1692 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001693
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01001694 @skip_if_broken_ubuntu_ssl
1695 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
1696 "TLS version 1.1 not supported.")
1697 def test_protocol_tlsv1_1(self):
1698 """Connecting to a TLSv1.1 server with various client options.
1699 Testing against older TLS versions."""
1700 if support.verbose:
1701 sys.stdout.write("\n")
1702 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, True)
1703 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1704 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
1705 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
1706 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
1707 client_options=ssl.OP_NO_TLSv1_1)
1708
1709 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, True)
1710 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
1711 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
1712
1713
1714 @skip_if_broken_ubuntu_ssl
1715 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
1716 "TLS version 1.2 not supported.")
1717 def test_protocol_tlsv1_2(self):
1718 """Connecting to a TLSv1.2 server with various client options.
1719 Testing against older TLS versions."""
1720 if support.verbose:
1721 sys.stdout.write("\n")
1722 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, True,
1723 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
1724 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
1725 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1726 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
1727 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
1728 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
1729 client_options=ssl.OP_NO_TLSv1_2)
1730
1731 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, True)
1732 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
1733 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
1734 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
1735 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
1736
Antoine Pitrou480a1242010-04-28 21:37:09 +00001737 def test_starttls(self):
1738 """Switching from clear text to encrypted and back again."""
1739 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 +00001740
Trent Nelson78520002008-04-10 20:54:35 +00001741 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001742 ssl_version=ssl.PROTOCOL_TLSv1,
1743 starttls_server=True,
1744 chatty=True,
1745 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001746 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001747 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001748 s = socket.socket()
1749 s.setblocking(1)
1750 s.connect((HOST, server.port))
1751 if support.verbose:
1752 sys.stdout.write("\n")
1753 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001754 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001755 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001756 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001757 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001758 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001759 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001760 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001761 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001762 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00001763 msg = outdata.strip().lower()
1764 if indata == b"STARTTLS" and msg.startswith(b"ok"):
1765 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001766 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001767 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001768 " client: read %r from server, starting TLS...\n"
1769 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001770 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1771 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00001772 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1773 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001774 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001775 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001776 " client: read %r from server, ending TLS...\n"
1777 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001778 s = conn.unwrap()
1779 wrapped = False
1780 else:
1781 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001782 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001783 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001784 if support.verbose:
1785 sys.stdout.write(" client: closing connection.\n")
1786 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001787 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001788 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001789 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00001790 if wrapped:
1791 conn.close()
1792 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001793 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001794
Antoine Pitrou480a1242010-04-28 21:37:09 +00001795 def test_socketserver(self):
1796 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01001797 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001798 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001799 if support.verbose:
1800 sys.stdout.write('\n')
1801 with open(CERTFILE, 'rb') as f:
1802 d1 = f.read()
1803 d2 = ''
1804 # now fetch the same data from the HTTPS server
1805 url = 'https://%s:%d/%s' % (
1806 HOST, server.port, os.path.split(CERTFILE)[1])
1807 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001808 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00001809 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001810 if dlen and (int(dlen) > 0):
1811 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001812 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001813 sys.stdout.write(
1814 " client: read %d bytes from remote server '%s'\n"
1815 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001816 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001817 f.close()
1818 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001819
Antoine Pitrou480a1242010-04-28 21:37:09 +00001820 def test_asyncore_server(self):
1821 """Check the example asyncore integration."""
1822 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00001823
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001824 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001825 sys.stdout.write("\n")
1826
Antoine Pitrou480a1242010-04-28 21:37:09 +00001827 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00001828 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001829 with server:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001830 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001831 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001832 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001833 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001834 " client: sending %r...\n" % indata)
1835 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001836 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001837 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001838 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00001839 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001840 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00001841 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1842 % (outdata[:20], len(outdata),
1843 indata[:20].lower(), len(indata)))
1844 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001845 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00001846 sys.stdout.write(" client: closing connection.\n")
1847 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00001848 if support.verbose:
1849 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00001850
Antoine Pitrou480a1242010-04-28 21:37:09 +00001851 def test_recv_send(self):
1852 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00001853 if support.verbose:
1854 sys.stdout.write("\n")
1855
1856 server = ThreadedEchoServer(CERTFILE,
1857 certreqs=ssl.CERT_NONE,
1858 ssl_version=ssl.PROTOCOL_TLSv1,
1859 cacerts=CERTFILE,
1860 chatty=True,
1861 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001862 with server:
1863 s = ssl.wrap_socket(socket.socket(),
1864 server_side=False,
1865 certfile=CERTFILE,
1866 ca_certs=CERTFILE,
1867 cert_reqs=ssl.CERT_NONE,
1868 ssl_version=ssl.PROTOCOL_TLSv1)
1869 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00001870 # helper methods for standardising recv* method signatures
1871 def _recv_into():
1872 b = bytearray(b"\0"*100)
1873 count = s.recv_into(b)
1874 return b[:count]
1875
1876 def _recvfrom_into():
1877 b = bytearray(b"\0"*100)
1878 count, addr = s.recvfrom_into(b)
1879 return b[:count]
1880
1881 # (name, method, whether to expect success, *args)
1882 send_methods = [
1883 ('send', s.send, True, []),
1884 ('sendto', s.sendto, False, ["some.address"]),
1885 ('sendall', s.sendall, True, []),
1886 ]
1887 recv_methods = [
1888 ('recv', s.recv, True, []),
1889 ('recvfrom', s.recvfrom, False, ["some.address"]),
1890 ('recv_into', _recv_into, True, []),
1891 ('recvfrom_into', _recvfrom_into, False, []),
1892 ]
1893 data_prefix = "PREFIX_"
1894
1895 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001896 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001897 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001898 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001899 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001900 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001901 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001902 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001903 "<<{outdata:r}>> ({nout:d}) received; "
1904 "expected <<{indata:r}>> ({nin:d})\n".format(
1905 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001906 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001907 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001908 )
1909 )
1910 except ValueError as e:
1911 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001912 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001913 "Failed to send with method <<{name:s}>>; "
1914 "expected to succeed.\n".format(name=meth_name)
1915 )
1916 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001917 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001918 "Method <<{name:s}>> failed with unexpected "
1919 "exception message: {exp:s}\n".format(
1920 name=meth_name, exp=e
1921 )
1922 )
1923
1924 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001925 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00001926 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001927 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001928 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001929 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00001930 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001931 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00001932 "<<{outdata:r}>> ({nout:d}) received; "
1933 "expected <<{indata:r}>> ({nin:d})\n".format(
1934 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00001935 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00001936 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00001937 )
1938 )
1939 except ValueError as e:
1940 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00001941 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001942 "Failed to receive with method <<{name:s}>>; "
1943 "expected to succeed.\n".format(name=meth_name)
1944 )
1945 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00001946 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00001947 "Method <<{name:s}>> failed with unexpected "
1948 "exception message: {exp:s}\n".format(
1949 name=meth_name, exp=e
1950 )
1951 )
1952 # consume data
1953 s.read()
1954
Nick Coghlan513886a2011-08-28 00:00:27 +10001955 # Make sure sendmsg et al are disallowed to avoid
1956 # inadvertent disclosure of data and/or corruption
1957 # of the encrypted data stream
1958 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
1959 self.assertRaises(NotImplementedError, s.recvmsg, 100)
1960 self.assertRaises(NotImplementedError,
1961 s.recvmsg_into, bytearray(100))
1962
Antoine Pitrou480a1242010-04-28 21:37:09 +00001963 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00001964 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00001965
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001966 def test_handshake_timeout(self):
1967 # Issue #5103: SSL handshake must respect the socket timeout
1968 server = socket.socket(socket.AF_INET)
1969 host = "127.0.0.1"
1970 port = support.bind_port(server)
1971 started = threading.Event()
1972 finish = False
1973
1974 def serve():
1975 server.listen(5)
1976 started.set()
1977 conns = []
1978 while not finish:
1979 r, w, e = select.select([server], [], [], 0.1)
1980 if server in r:
1981 # Let the socket hang around rather than having
1982 # it closed by garbage collection.
1983 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00001984 for sock in conns:
1985 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001986
1987 t = threading.Thread(target=serve)
1988 t.start()
1989 started.wait()
1990
1991 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00001992 try:
1993 c = socket.socket(socket.AF_INET)
1994 c.settimeout(0.2)
1995 c.connect((host, port))
1996 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00001997 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00001998 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00001999 finally:
2000 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002001 try:
2002 c = socket.socket(socket.AF_INET)
2003 c = ssl.wrap_socket(c)
2004 c.settimeout(0.2)
2005 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002006 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002007 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002008 finally:
2009 c.close()
2010 finally:
2011 finish = True
2012 t.join()
2013 server.close()
2014
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002015 def test_server_accept(self):
2016 # Issue #16357: accept() on a SSLSocket created through
2017 # SSLContext.wrap_socket().
2018 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2019 context.verify_mode = ssl.CERT_REQUIRED
2020 context.load_verify_locations(CERTFILE)
2021 context.load_cert_chain(CERTFILE)
2022 server = socket.socket(socket.AF_INET)
2023 host = "127.0.0.1"
2024 port = support.bind_port(server)
2025 server = context.wrap_socket(server, server_side=True)
2026
2027 evt = threading.Event()
2028 remote = None
2029 peer = None
2030 def serve():
2031 nonlocal remote, peer
2032 server.listen(5)
2033 # Block on the accept and wait on the connection to close.
2034 evt.set()
2035 remote, peer = server.accept()
2036 remote.recv(1)
2037
2038 t = threading.Thread(target=serve)
2039 t.start()
2040 # Client wait until server setup and perform a connect.
2041 evt.wait()
2042 client = context.wrap_socket(socket.socket())
2043 client.connect((host, port))
2044 client_addr = client.getsockname()
2045 client.close()
2046 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002047 remote.close()
2048 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002049 # Sanity checks.
2050 self.assertIsInstance(remote, ssl.SSLSocket)
2051 self.assertEqual(peer, client_addr)
2052
Antoine Pitrou242db722013-05-01 20:52:07 +02002053 def test_getpeercert_enotconn(self):
2054 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2055 with context.wrap_socket(socket.socket()) as sock:
2056 with self.assertRaises(OSError) as cm:
2057 sock.getpeercert()
2058 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2059
2060 def test_do_handshake_enotconn(self):
2061 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2062 with context.wrap_socket(socket.socket()) as sock:
2063 with self.assertRaises(OSError) as cm:
2064 sock.do_handshake()
2065 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2066
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002067 def test_default_ciphers(self):
2068 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2069 try:
2070 # Force a set of weak ciphers on our client context
2071 context.set_ciphers("DES")
2072 except ssl.SSLError:
2073 self.skipTest("no DES cipher available")
2074 with ThreadedEchoServer(CERTFILE,
2075 ssl_version=ssl.PROTOCOL_SSLv23,
2076 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002077 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02002078 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002079 s.connect((HOST, server.port))
2080 self.assertIn("no shared cipher", str(server.conn_errors[0]))
2081
Antoine Pitroud6494802011-07-21 01:11:30 +02002082 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
2083 "'tls-unique' channel binding not available")
2084 def test_tls_unique_channel_binding(self):
2085 """Test tls-unique channel binding."""
2086 if support.verbose:
2087 sys.stdout.write("\n")
2088
2089 server = ThreadedEchoServer(CERTFILE,
2090 certreqs=ssl.CERT_NONE,
2091 ssl_version=ssl.PROTOCOL_TLSv1,
2092 cacerts=CERTFILE,
2093 chatty=True,
2094 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01002095 with server:
2096 s = ssl.wrap_socket(socket.socket(),
2097 server_side=False,
2098 certfile=CERTFILE,
2099 ca_certs=CERTFILE,
2100 cert_reqs=ssl.CERT_NONE,
2101 ssl_version=ssl.PROTOCOL_TLSv1)
2102 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02002103 # get the data
2104 cb_data = s.get_channel_binding("tls-unique")
2105 if support.verbose:
2106 sys.stdout.write(" got channel binding data: {0!r}\n"
2107 .format(cb_data))
2108
2109 # check if it is sane
2110 self.assertIsNotNone(cb_data)
2111 self.assertEqual(len(cb_data), 12) # True for TLSv1
2112
2113 # and compare with the peers version
2114 s.write(b"CB tls-unique\n")
2115 peer_data_repr = s.read().strip()
2116 self.assertEqual(peer_data_repr,
2117 repr(cb_data).encode("us-ascii"))
2118 s.close()
2119
2120 # now, again
2121 s = ssl.wrap_socket(socket.socket(),
2122 server_side=False,
2123 certfile=CERTFILE,
2124 ca_certs=CERTFILE,
2125 cert_reqs=ssl.CERT_NONE,
2126 ssl_version=ssl.PROTOCOL_TLSv1)
2127 s.connect((HOST, server.port))
2128 new_cb_data = s.get_channel_binding("tls-unique")
2129 if support.verbose:
2130 sys.stdout.write(" got another channel binding data: {0!r}\n"
2131 .format(new_cb_data))
2132 # is it really unique
2133 self.assertNotEqual(cb_data, new_cb_data)
2134 self.assertIsNotNone(cb_data)
2135 self.assertEqual(len(cb_data), 12) # True for TLSv1
2136 s.write(b"CB tls-unique\n")
2137 peer_data_repr = s.read().strip()
2138 self.assertEqual(peer_data_repr,
2139 repr(new_cb_data).encode("us-ascii"))
2140 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002141
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002142 def test_compression(self):
2143 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2144 context.load_cert_chain(CERTFILE)
2145 stats = server_params_test(context, context,
2146 chatty=True, connectionchatty=True)
2147 if support.verbose:
2148 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
2149 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
2150
2151 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
2152 "ssl.OP_NO_COMPRESSION needed for this test")
2153 def test_compression_disabled(self):
2154 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2155 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01002156 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002157 stats = server_params_test(context, context,
2158 chatty=True, connectionchatty=True)
2159 self.assertIs(stats['compression'], None)
2160
Antoine Pitrou0e576f12011-12-22 10:03:38 +01002161 def test_dh_params(self):
2162 # Check we can get a connection with ephemeral Diffie-Hellman
2163 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2164 context.load_cert_chain(CERTFILE)
2165 context.load_dh_params(DHFILE)
2166 context.set_ciphers("kEDH")
2167 stats = server_params_test(context, context,
2168 chatty=True, connectionchatty=True)
2169 cipher = stats["cipher"][0]
2170 parts = cipher.split("-")
2171 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
2172 self.fail("Non-DH cipher: " + cipher[0])
2173
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002174 def test_selected_npn_protocol(self):
2175 # selected_npn_protocol() is None unless NPN is used
2176 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2177 context.load_cert_chain(CERTFILE)
2178 stats = server_params_test(context, context,
2179 chatty=True, connectionchatty=True)
2180 self.assertIs(stats['client_npn_protocol'], None)
2181
2182 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
2183 def test_npn_protocols(self):
2184 server_protocols = ['http/1.1', 'spdy/2']
2185 protocol_tests = [
2186 (['http/1.1', 'spdy/2'], 'http/1.1'),
2187 (['spdy/2', 'http/1.1'], 'http/1.1'),
2188 (['spdy/2', 'test'], 'spdy/2'),
2189 (['abc', 'def'], 'abc')
2190 ]
2191 for client_protocols, expected in protocol_tests:
2192 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2193 server_context.load_cert_chain(CERTFILE)
2194 server_context.set_npn_protocols(server_protocols)
2195 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2196 client_context.load_cert_chain(CERTFILE)
2197 client_context.set_npn_protocols(client_protocols)
2198 stats = server_params_test(client_context, server_context,
2199 chatty=True, connectionchatty=True)
2200
2201 msg = "failed trying %s (s) and %s (c).\n" \
2202 "was expecting %s, but got %%s from the %%s" \
2203 % (str(server_protocols), str(client_protocols),
2204 str(expected))
2205 client_result = stats['client_npn_protocol']
2206 self.assertEqual(client_result, expected, msg % (client_result, "client"))
2207 server_result = stats['server_npn_protocols'][-1] \
2208 if len(stats['server_npn_protocols']) else 'nothing'
2209 self.assertEqual(server_result, expected, msg % (server_result, "server"))
2210
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002211 def sni_contexts(self):
2212 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2213 server_context.load_cert_chain(SIGNED_CERTFILE)
2214 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2215 other_context.load_cert_chain(SIGNED_CERTFILE2)
2216 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2217 client_context.verify_mode = ssl.CERT_REQUIRED
2218 client_context.load_verify_locations(SIGNING_CA)
2219 return server_context, other_context, client_context
2220
2221 def check_common_name(self, stats, name):
2222 cert = stats['peercert']
2223 self.assertIn((('commonName', name),), cert['subject'])
2224
2225 @needs_sni
2226 def test_sni_callback(self):
2227 calls = []
2228 server_context, other_context, client_context = self.sni_contexts()
2229
2230 def servername_cb(ssl_sock, server_name, initial_context):
2231 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02002232 if server_name is not None:
2233 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002234 server_context.set_servername_callback(servername_cb)
2235
2236 stats = server_params_test(client_context, server_context,
2237 chatty=True,
2238 sni_name='supermessage')
2239 # The hostname was fetched properly, and the certificate was
2240 # changed for the connection.
2241 self.assertEqual(calls, [("supermessage", server_context)])
2242 # CERTFILE4 was selected
2243 self.check_common_name(stats, 'fakehostname')
2244
Antoine Pitrou50b24d02013-04-11 20:48:42 +02002245 calls = []
2246 # The callback is called with server_name=None
2247 stats = server_params_test(client_context, server_context,
2248 chatty=True,
2249 sni_name=None)
2250 self.assertEqual(calls, [(None, server_context)])
2251 self.check_common_name(stats, 'localhost')
2252
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002253 # Check disabling the callback
2254 calls = []
2255 server_context.set_servername_callback(None)
2256
2257 stats = server_params_test(client_context, server_context,
2258 chatty=True,
2259 sni_name='notfunny')
2260 # Certificate didn't change
2261 self.check_common_name(stats, 'localhost')
2262 self.assertEqual(calls, [])
2263
2264 @needs_sni
2265 def test_sni_callback_alert(self):
2266 # Returning a TLS alert is reflected to the connecting client
2267 server_context, other_context, client_context = self.sni_contexts()
2268
2269 def cb_returning_alert(ssl_sock, server_name, initial_context):
2270 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
2271 server_context.set_servername_callback(cb_returning_alert)
2272
2273 with self.assertRaises(ssl.SSLError) as cm:
2274 stats = server_params_test(client_context, server_context,
2275 chatty=False,
2276 sni_name='supermessage')
2277 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
2278
2279 @needs_sni
2280 def test_sni_callback_raising(self):
2281 # Raising fails the connection with a TLS handshake failure alert.
2282 server_context, other_context, client_context = self.sni_contexts()
2283
2284 def cb_raising(ssl_sock, server_name, initial_context):
2285 1/0
2286 server_context.set_servername_callback(cb_raising)
2287
2288 with self.assertRaises(ssl.SSLError) as cm, \
2289 support.captured_stderr() as stderr:
2290 stats = server_params_test(client_context, server_context,
2291 chatty=False,
2292 sni_name='supermessage')
2293 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
2294 self.assertIn("ZeroDivisionError", stderr.getvalue())
2295
2296 @needs_sni
2297 def test_sni_callback_wrong_return_type(self):
2298 # Returning the wrong return type terminates the TLS connection
2299 # with an internal error alert.
2300 server_context, other_context, client_context = self.sni_contexts()
2301
2302 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
2303 return "foo"
2304 server_context.set_servername_callback(cb_wrong_return_type)
2305
2306 with self.assertRaises(ssl.SSLError) as cm, \
2307 support.captured_stderr() as stderr:
2308 stats = server_params_test(client_context, server_context,
2309 chatty=False,
2310 sni_name='supermessage')
2311 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
2312 self.assertIn("TypeError", stderr.getvalue())
2313
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002314
Thomas Woutersed03b412007-08-28 21:37:11 +00002315def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00002316 if support.verbose:
2317 plats = {
2318 'Linux': platform.linux_distribution,
2319 'Mac': platform.mac_ver,
2320 'Windows': platform.win32_ver,
2321 }
2322 for name, func in plats.items():
2323 plat = func()
2324 if plat and plat[0]:
2325 plat = '%s %r' % (name, plat)
2326 break
2327 else:
2328 plat = repr(platform.platform())
2329 print("test_ssl: testing with %r %r" %
2330 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
2331 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00002332 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01002333 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
2334 try:
2335 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
2336 except AttributeError:
2337 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00002338
Antoine Pitrou152efa22010-05-16 18:19:27 +00002339 for filename in [
2340 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
2341 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002342 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00002343 BADCERT, BADKEY, EMPTYCERT]:
2344 if not os.path.exists(filename):
2345 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002346
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02002347 tests = [ContextTests, BasicSocketTests, SSLErrorTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00002348
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002349 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00002350 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00002351
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002352 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002353 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01002354 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00002355 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00002356
Antoine Pitrou480a1242010-04-28 21:37:09 +00002357 try:
2358 support.run_unittest(*tests)
2359 finally:
2360 if _have_threads:
2361 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00002362
2363if __name__ == "__main__":
2364 test_main()