blob: f48103e2c178dc6a9efe86ed6ec215821b98f182 [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
Thomas Woutersed03b412007-08-28 21:37:11 +000021
Antoine Pitrou05d936d2010-10-13 11:38:36 +000022ssl = support.import_module("ssl")
23
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010024PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000025HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000026
Christian Heimesefff7062013-11-21 03:35:02 +010027def data_file(*name):
28 return 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)
Christian Heimesefff7062013-11-21 03:35:02 +010046CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
47CAFILE_CACERT = data_file("capath", "5ed36f99.0")
48
Antoine Pitrou152efa22010-05-16 18:19:27 +000049
Christian Heimes22587792013-11-21 23:56:13 +010050# empty CRL
51CRLFILE = data_file("revocation.crl")
52
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010053# Two keys and certs signed by the same CA (for SNI tests)
54SIGNED_CERTFILE = data_file("keycert3.pem")
55SIGNED_CERTFILE2 = data_file("keycert4.pem")
56SIGNING_CA = data_file("pycacert.pem")
57
Martin Panter3d81d932016-01-14 09:36:00 +000058REMOTE_HOST = "self-signed.pythontest.net"
59REMOTE_ROOT_CERT = data_file("selfsigned_pythontestdotnet.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000060
61EMPTYCERT = data_file("nullcert.pem")
62BADCERT = data_file("badcert.pem")
Martin Panter407b62f2016-01-30 03:41:43 +000063NONEXISTINGCERT = data_file("XXXnonexisting.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000064BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020065NOKIACERT = data_file("nokia.pem")
Christian Heimes824f7f32013-08-17 00:54:47 +020066NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000067
Benjamin Petersona7eaf562015-04-02 00:04:06 -040068DHFILE = data_file("dh1024.pem")
Antoine Pitrou0e576f12011-12-22 10:03:38 +010069BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000070
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010071
Thomas Woutersed03b412007-08-28 21:37:11 +000072def handle_error(prefix):
73 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000074 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000075 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000076
Antoine Pitroub5218772010-05-21 09:56:06 +000077def can_clear_options():
78 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020079 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000080
81def no_sslv2_implies_sslv3_hello():
82 # 0.9.7h or higher
83 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
84
Christian Heimes2427b502013-11-23 11:24:32 +010085def have_verify_flags():
86 # 0.9.8 or higher
87 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
88
Antoine Pitrouc695c952014-04-28 20:57:36 +020089def utc_offset(): #NOTE: ignore issues like #1647654
90 # local time = utc time + utc offset
91 if time.daylight and time.localtime().tm_isdst > 0:
92 return -time.altzone # seconds
93 return -time.timezone
94
Christian Heimes9424bb42013-06-17 15:32:57 +020095def asn1time(cert_time):
96 # Some versions of OpenSSL ignore seconds, see #18207
97 # 0.9.8.i
98 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
99 fmt = "%b %d %H:%M:%S %Y GMT"
100 dt = datetime.datetime.strptime(cert_time, fmt)
101 dt = dt.replace(second=0)
102 cert_time = dt.strftime(fmt)
103 # %d adds leading zero but ASN1_TIME_print() uses leading space
104 if cert_time[4] == "0":
105 cert_time = cert_time[:4] + " " + cert_time[5:]
106
107 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +0000108
Antoine Pitrou23df4832010-08-04 17:14:06 +0000109# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
110def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +0200111 if hasattr(ssl, 'PROTOCOL_SSLv2'):
112 @functools.wraps(func)
113 def f(*args, **kwargs):
114 try:
115 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
116 except ssl.SSLError:
117 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
118 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
119 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
120 return func(*args, **kwargs)
121 return f
122 else:
123 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000124
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100125needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
126
Antoine Pitrou23df4832010-08-04 17:14:06 +0000127
Antoine Pitrou152efa22010-05-16 18:19:27 +0000128class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000129
Antoine Pitrou480a1242010-04-28 21:37:09 +0000130 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000131 ssl.CERT_NONE
132 ssl.CERT_OPTIONAL
133 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100134 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100135 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100136 if ssl.HAS_ECDH:
137 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100138 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
139 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000140 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100141 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000142
Antoine Pitrou172f0252014-04-18 20:33:08 +0200143 def test_str_for_enums(self):
144 # Make sure that the PROTOCOL_* constants have enum-like string
145 # reprs.
Victor Stinner648b8622014-12-12 12:23:59 +0100146 proto = ssl.PROTOCOL_SSLv23
147 self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_SSLv23')
Antoine Pitrou172f0252014-04-18 20:33:08 +0200148 ctx = ssl.SSLContext(proto)
149 self.assertIs(ctx.protocol, proto)
150
Antoine Pitrou480a1242010-04-28 21:37:09 +0000151 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000152 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000153 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000154 sys.stdout.write("\n RAND_status is %d (%s)\n"
155 % (v, (v and "sufficient randomness") or
156 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200157
158 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
159 self.assertEqual(len(data), 16)
160 self.assertEqual(is_cryptographic, v == 1)
161 if v:
162 data = ssl.RAND_bytes(16)
163 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200164 else:
165 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200166
Victor Stinner1e81a392013-12-19 16:47:04 +0100167 # negative num is invalid
168 self.assertRaises(ValueError, ssl.RAND_bytes, -5)
169 self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5)
170
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100171 if hasattr(ssl, 'RAND_egd'):
172 self.assertRaises(TypeError, ssl.RAND_egd, 1)
173 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000174 ssl.RAND_add("this is a random string", 75.0)
Serhiy Storchaka8490f5a2015-03-20 09:00:36 +0200175 ssl.RAND_add(b"this is a random bytes object", 75.0)
176 ssl.RAND_add(bytearray(b"this is a random bytearray object"), 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000177
Christian Heimesf77b4b22013-08-21 13:26:05 +0200178 @unittest.skipUnless(os.name == 'posix', 'requires posix')
179 def test_random_fork(self):
180 status = ssl.RAND_status()
181 if not status:
182 self.fail("OpenSSL's PRNG has insufficient randomness")
183
184 rfd, wfd = os.pipe()
185 pid = os.fork()
186 if pid == 0:
187 try:
188 os.close(rfd)
189 child_random = ssl.RAND_pseudo_bytes(16)[0]
190 self.assertEqual(len(child_random), 16)
191 os.write(wfd, child_random)
192 os.close(wfd)
193 except BaseException:
194 os._exit(1)
195 else:
196 os._exit(0)
197 else:
198 os.close(wfd)
199 self.addCleanup(os.close, rfd)
200 _, status = os.waitpid(pid, 0)
201 self.assertEqual(status, 0)
202
203 child_random = os.read(rfd, 16)
204 self.assertEqual(len(child_random), 16)
205 parent_random = ssl.RAND_pseudo_bytes(16)[0]
206 self.assertEqual(len(parent_random), 16)
207
208 self.assertNotEqual(child_random, parent_random)
209
Antoine Pitrou480a1242010-04-28 21:37:09 +0000210 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000211 # note that this uses an 'unofficial' function in _ssl.c,
212 # provided solely for this test, to exercise the certificate
213 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000214 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000215 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000216 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200217 self.assertEqual(p['issuer'],
218 ((('countryName', 'XY'),),
219 (('localityName', 'Castle Anthrax'),),
220 (('organizationName', 'Python Software Foundation'),),
221 (('commonName', 'localhost'),))
222 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100223 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200224 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
225 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200226 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
227 self.assertEqual(p['subject'],
228 ((('countryName', 'XY'),),
229 (('localityName', 'Castle Anthrax'),),
230 (('organizationName', 'Python Software Foundation'),),
231 (('commonName', 'localhost'),))
232 )
233 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
234 # Issue #13034: the subjectAltName in some certificates
235 # (notably projects.developer.nokia.com:443) wasn't parsed
236 p = ssl._ssl._test_decode_cert(NOKIACERT)
237 if support.verbose:
238 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
239 self.assertEqual(p['subjectAltName'],
240 (('DNS', 'projects.developer.nokia.com'),
241 ('DNS', 'projects.forum.nokia.com'))
242 )
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100243 # extra OCSP and AIA fields
244 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
245 self.assertEqual(p['caIssuers'],
246 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
247 self.assertEqual(p['crlDistributionPoints'],
248 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Thomas Woutersed03b412007-08-28 21:37:11 +0000249
Christian Heimes824f7f32013-08-17 00:54:47 +0200250 def test_parse_cert_CVE_2013_4238(self):
251 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
252 if support.verbose:
253 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
254 subject = ((('countryName', 'US'),),
255 (('stateOrProvinceName', 'Oregon'),),
256 (('localityName', 'Beaverton'),),
257 (('organizationName', 'Python Software Foundation'),),
258 (('organizationalUnitName', 'Python Core Development'),),
259 (('commonName', 'null.python.org\x00example.org'),),
260 (('emailAddress', 'python-dev@python.org'),))
261 self.assertEqual(p['subject'], subject)
262 self.assertEqual(p['issuer'], subject)
Christian Heimes157c9832013-08-25 14:12:41 +0200263 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
264 san = (('DNS', 'altnull.python.org\x00example.com'),
265 ('email', 'null@python.org\x00user@example.org'),
266 ('URI', 'http://null.python.org\x00http://example.org'),
267 ('IP Address', '192.0.2.1'),
268 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
269 else:
270 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
271 san = (('DNS', 'altnull.python.org\x00example.com'),
272 ('email', 'null@python.org\x00user@example.org'),
273 ('URI', 'http://null.python.org\x00http://example.org'),
274 ('IP Address', '192.0.2.1'),
275 ('IP Address', '<invalid>'))
276
277 self.assertEqual(p['subjectAltName'], san)
Christian Heimes824f7f32013-08-17 00:54:47 +0200278
Antoine Pitrou480a1242010-04-28 21:37:09 +0000279 def test_DER_to_PEM(self):
Martin Panter3d81d932016-01-14 09:36:00 +0000280 with open(CAFILE_CACERT, 'r') as f:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000281 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000282 d1 = ssl.PEM_cert_to_DER_cert(pem)
283 p2 = ssl.DER_cert_to_PEM_cert(d1)
284 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000285 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000286 if not p2.startswith(ssl.PEM_HEADER + '\n'):
287 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
288 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
289 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000290
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000291 def test_openssl_version(self):
292 n = ssl.OPENSSL_VERSION_NUMBER
293 t = ssl.OPENSSL_VERSION_INFO
294 s = ssl.OPENSSL_VERSION
295 self.assertIsInstance(n, int)
296 self.assertIsInstance(t, tuple)
297 self.assertIsInstance(s, str)
298 # Some sanity checks follow
299 # >= 0.9
300 self.assertGreaterEqual(n, 0x900000)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400301 # < 3.0
302 self.assertLess(n, 0x30000000)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000303 major, minor, fix, patch, status = t
304 self.assertGreaterEqual(major, 0)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400305 self.assertLess(major, 3)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000306 self.assertGreaterEqual(minor, 0)
307 self.assertLess(minor, 256)
308 self.assertGreaterEqual(fix, 0)
309 self.assertLess(fix, 256)
310 self.assertGreaterEqual(patch, 0)
Ned Deily05784a72015-02-05 17:20:13 +1100311 self.assertLessEqual(patch, 63)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000312 self.assertGreaterEqual(status, 0)
313 self.assertLessEqual(status, 15)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400314 # Version string as returned by {Open,Libre}SSL, the format might change
315 if "LibreSSL" in s:
316 self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)),
Victor Stinner789b8052015-01-06 11:51:06 +0100317 (s, t, hex(n)))
Antoine Pitroudfab9352014-07-21 18:35:01 -0400318 else:
319 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
Victor Stinner789b8052015-01-06 11:51:06 +0100320 (s, t, hex(n)))
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000321
Antoine Pitrou9d543662010-04-23 23:10:32 +0000322 @support.cpython_only
323 def test_refcycle(self):
324 # Issue #7943: an SSL object doesn't create reference cycles with
325 # itself.
326 s = socket.socket(socket.AF_INET)
327 ss = ssl.wrap_socket(s)
328 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100329 with support.check_warnings(("", ResourceWarning)):
330 del ss
331 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000332
Antoine Pitroua468adc2010-09-14 14:43:44 +0000333 def test_wrapped_unconnected(self):
334 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200335 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000336 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100337 with ssl.wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100338 self.assertRaises(OSError, ss.recv, 1)
339 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
340 self.assertRaises(OSError, ss.recvfrom, 1)
341 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
342 self.assertRaises(OSError, ss.send, b'x')
343 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000344
Antoine Pitrou40f08742010-04-24 22:04:40 +0000345 def test_timeout(self):
346 # Issue #8524: when creating an SSL socket, the timeout of the
347 # original socket should be retained.
348 for timeout in (None, 0.0, 5.0):
349 s = socket.socket(socket.AF_INET)
350 s.settimeout(timeout)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100351 with ssl.wrap_socket(s) as ss:
352 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000353
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000354 def test_errors(self):
355 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000356 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000357 "certfile must be specified",
358 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000359 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000360 "certfile must be specified for server-side operations",
361 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000362 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000363 "certfile must be specified for server-side operations",
364 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100365 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
366 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
367 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200368 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000369 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000370 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000371 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200372 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000373 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000374 ssl.wrap_socket(sock,
375 certfile=CERTFILE, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000376 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200377 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000378 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000379 ssl.wrap_socket(sock,
380 certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000381 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000382
Martin Panter3464ea22016-02-01 21:58:11 +0000383 def bad_cert_test(self, certfile):
384 """Check that trying to use the given client certificate fails"""
385 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
386 certfile)
387 sock = socket.socket()
388 self.addCleanup(sock.close)
389 with self.assertRaises(ssl.SSLError):
390 ssl.wrap_socket(sock,
391 certfile=certfile,
392 ssl_version=ssl.PROTOCOL_TLSv1)
393
394 def test_empty_cert(self):
395 """Wrapping with an empty cert file"""
396 self.bad_cert_test("nullcert.pem")
397
398 def test_malformed_cert(self):
399 """Wrapping with a badly formatted certificate (syntax error)"""
400 self.bad_cert_test("badcert.pem")
401
402 def test_malformed_key(self):
403 """Wrapping with a badly formatted key (syntax error)"""
404 self.bad_cert_test("badkey.pem")
405
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000406 def test_match_hostname(self):
407 def ok(cert, hostname):
408 ssl.match_hostname(cert, hostname)
409 def fail(cert, hostname):
410 self.assertRaises(ssl.CertificateError,
411 ssl.match_hostname, cert, hostname)
412
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100413 # -- Hostname matching --
414
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000415 cert = {'subject': ((('commonName', 'example.com'),),)}
416 ok(cert, 'example.com')
417 ok(cert, 'ExAmple.cOm')
418 fail(cert, 'www.example.com')
419 fail(cert, '.example.com')
420 fail(cert, 'example.org')
421 fail(cert, 'exampleXcom')
422
423 cert = {'subject': ((('commonName', '*.a.com'),),)}
424 ok(cert, 'foo.a.com')
425 fail(cert, 'bar.foo.a.com')
426 fail(cert, 'a.com')
427 fail(cert, 'Xa.com')
428 fail(cert, '.a.com')
429
Georg Brandl72c98d32013-10-27 07:16:53 +0100430 # only match one left-most wildcard
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000431 cert = {'subject': ((('commonName', 'f*.com'),),)}
432 ok(cert, 'foo.com')
433 ok(cert, 'f.com')
434 fail(cert, 'bar.com')
435 fail(cert, 'foo.a.com')
436 fail(cert, 'bar.foo.com')
437
Christian Heimes824f7f32013-08-17 00:54:47 +0200438 # NULL bytes are bad, CVE-2013-4073
439 cert = {'subject': ((('commonName',
440 'null.python.org\x00example.org'),),)}
441 ok(cert, 'null.python.org\x00example.org') # or raise an error?
442 fail(cert, 'example.org')
443 fail(cert, 'null.python.org')
444
Georg Brandl72c98d32013-10-27 07:16:53 +0100445 # error cases with wildcards
446 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
447 fail(cert, 'bar.foo.a.com')
448 fail(cert, 'a.com')
449 fail(cert, 'Xa.com')
450 fail(cert, '.a.com')
451
452 cert = {'subject': ((('commonName', 'a.*.com'),),)}
453 fail(cert, 'a.foo.com')
454 fail(cert, 'a..com')
455 fail(cert, 'a.com')
456
457 # wildcard doesn't match IDNA prefix 'xn--'
458 idna = 'püthon.python.org'.encode("idna").decode("ascii")
459 cert = {'subject': ((('commonName', idna),),)}
460 ok(cert, idna)
461 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
462 fail(cert, idna)
463 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
464 fail(cert, idna)
465
466 # wildcard in first fragment and IDNA A-labels in sequent fragments
467 # are supported.
468 idna = 'www*.pythön.org'.encode("idna").decode("ascii")
469 cert = {'subject': ((('commonName', idna),),)}
470 ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
471 ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
472 fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
473 fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
474
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000475 # Slightly fake real-world example
476 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
477 'subject': ((('commonName', 'linuxfrz.org'),),),
478 'subjectAltName': (('DNS', 'linuxfr.org'),
479 ('DNS', 'linuxfr.com'),
480 ('othername', '<unsupported>'))}
481 ok(cert, 'linuxfr.org')
482 ok(cert, 'linuxfr.com')
483 # Not a "DNS" entry
484 fail(cert, '<unsupported>')
485 # When there is a subjectAltName, commonName isn't used
486 fail(cert, 'linuxfrz.org')
487
488 # A pristine real-world example
489 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
490 'subject': ((('countryName', 'US'),),
491 (('stateOrProvinceName', 'California'),),
492 (('localityName', 'Mountain View'),),
493 (('organizationName', 'Google Inc'),),
494 (('commonName', 'mail.google.com'),))}
495 ok(cert, 'mail.google.com')
496 fail(cert, 'gmail.com')
497 # Only commonName is considered
498 fail(cert, 'California')
499
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100500 # -- IPv4 matching --
501 cert = {'subject': ((('commonName', 'example.com'),),),
502 'subjectAltName': (('DNS', 'example.com'),
503 ('IP Address', '10.11.12.13'),
504 ('IP Address', '14.15.16.17'))}
505 ok(cert, '10.11.12.13')
506 ok(cert, '14.15.16.17')
507 fail(cert, '14.15.16.18')
508 fail(cert, 'example.net')
509
510 # -- IPv6 matching --
511 cert = {'subject': ((('commonName', 'example.com'),),),
512 'subjectAltName': (('DNS', 'example.com'),
513 ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'),
514 ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))}
515 ok(cert, '2001::cafe')
516 ok(cert, '2003::baba')
517 fail(cert, '2003::bebe')
518 fail(cert, 'example.net')
519
520 # -- Miscellaneous --
521
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000522 # Neither commonName nor subjectAltName
523 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
524 'subject': ((('countryName', 'US'),),
525 (('stateOrProvinceName', 'California'),),
526 (('localityName', 'Mountain View'),),
527 (('organizationName', 'Google Inc'),))}
528 fail(cert, 'mail.google.com')
529
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200530 # No DNS entry in subjectAltName but a commonName
531 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
532 'subject': ((('countryName', 'US'),),
533 (('stateOrProvinceName', 'California'),),
534 (('localityName', 'Mountain View'),),
535 (('commonName', 'mail.google.com'),)),
536 'subjectAltName': (('othername', 'blabla'), )}
537 ok(cert, 'mail.google.com')
538
539 # No DNS entry subjectAltName and no commonName
540 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
541 'subject': ((('countryName', 'US'),),
542 (('stateOrProvinceName', 'California'),),
543 (('localityName', 'Mountain View'),),
544 (('organizationName', 'Google Inc'),)),
545 'subjectAltName': (('othername', 'blabla'),)}
546 fail(cert, 'google.com')
547
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000548 # Empty cert / no cert
549 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
550 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
551
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200552 # Issue #17980: avoid denials of service by refusing more than one
553 # wildcard per fragment.
554 cert = {'subject': ((('commonName', 'a*b.com'),),)}
555 ok(cert, 'axxb.com')
556 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
Georg Brandl72c98d32013-10-27 07:16:53 +0100557 fail(cert, 'axxb.com')
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200558 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
559 with self.assertRaises(ssl.CertificateError) as cm:
560 ssl.match_hostname(cert, 'axxbxxc.com')
561 self.assertIn("too many wildcards", str(cm.exception))
562
Antoine Pitroud5323212010-10-22 18:19:07 +0000563 def test_server_side(self):
564 # server_hostname doesn't work for server sockets
565 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000566 with socket.socket() as sock:
567 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
568 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000569
Antoine Pitroud6494802011-07-21 01:11:30 +0200570 def test_unknown_channel_binding(self):
571 # should raise ValueError for unknown type
572 s = socket.socket(socket.AF_INET)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200573 s.bind(('127.0.0.1', 0))
574 s.listen()
575 c = socket.socket(socket.AF_INET)
576 c.connect(s.getsockname())
577 with ssl.wrap_socket(c, do_handshake_on_connect=False) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100578 with self.assertRaises(ValueError):
579 ss.get_channel_binding("unknown-type")
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200580 s.close()
Antoine Pitroud6494802011-07-21 01:11:30 +0200581
582 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
583 "'tls-unique' channel binding not available")
584 def test_tls_unique_channel_binding(self):
585 # unconnected should return None for known type
586 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100587 with ssl.wrap_socket(s) as ss:
588 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200589 # the same for server-side
590 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100591 with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
592 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200593
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600594 def test_dealloc_warn(self):
595 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
596 r = repr(ss)
597 with self.assertWarns(ResourceWarning) as cm:
598 ss = None
599 support.gc_collect()
600 self.assertIn(r, str(cm.warning.args[0]))
601
Christian Heimes6d7ad132013-06-09 18:02:55 +0200602 def test_get_default_verify_paths(self):
603 paths = ssl.get_default_verify_paths()
604 self.assertEqual(len(paths), 6)
605 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
606
607 with support.EnvironmentVarGuard() as env:
608 env["SSL_CERT_DIR"] = CAPATH
609 env["SSL_CERT_FILE"] = CERTFILE
610 paths = ssl.get_default_verify_paths()
611 self.assertEqual(paths.cafile, CERTFILE)
612 self.assertEqual(paths.capath, CAPATH)
613
Christian Heimes44109d72013-11-22 01:51:30 +0100614 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
615 def test_enum_certificates(self):
616 self.assertTrue(ssl.enum_certificates("CA"))
617 self.assertTrue(ssl.enum_certificates("ROOT"))
618
619 self.assertRaises(TypeError, ssl.enum_certificates)
620 self.assertRaises(WindowsError, ssl.enum_certificates, "")
621
Christian Heimesc2d65e12013-11-22 16:13:55 +0100622 trust_oids = set()
623 for storename in ("CA", "ROOT"):
624 store = ssl.enum_certificates(storename)
625 self.assertIsInstance(store, list)
626 for element in store:
627 self.assertIsInstance(element, tuple)
628 self.assertEqual(len(element), 3)
629 cert, enc, trust = element
630 self.assertIsInstance(cert, bytes)
631 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
632 self.assertIsInstance(trust, (set, bool))
633 if isinstance(trust, set):
634 trust_oids.update(trust)
Christian Heimes44109d72013-11-22 01:51:30 +0100635
636 serverAuth = "1.3.6.1.5.5.7.3.1"
Christian Heimesc2d65e12013-11-22 16:13:55 +0100637 self.assertIn(serverAuth, trust_oids)
Christian Heimes6d7ad132013-06-09 18:02:55 +0200638
Christian Heimes46bebee2013-06-09 19:03:31 +0200639 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Christian Heimes44109d72013-11-22 01:51:30 +0100640 def test_enum_crls(self):
641 self.assertTrue(ssl.enum_crls("CA"))
642 self.assertRaises(TypeError, ssl.enum_crls)
643 self.assertRaises(WindowsError, ssl.enum_crls, "")
Christian Heimes46bebee2013-06-09 19:03:31 +0200644
Christian Heimes44109d72013-11-22 01:51:30 +0100645 crls = ssl.enum_crls("CA")
646 self.assertIsInstance(crls, list)
647 for element in crls:
648 self.assertIsInstance(element, tuple)
649 self.assertEqual(len(element), 2)
650 self.assertIsInstance(element[0], bytes)
651 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
Christian Heimes46bebee2013-06-09 19:03:31 +0200652
Christian Heimes46bebee2013-06-09 19:03:31 +0200653
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100654 def test_asn1object(self):
655 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
656 '1.3.6.1.5.5.7.3.1')
657
658 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
659 self.assertEqual(val, expected)
660 self.assertEqual(val.nid, 129)
661 self.assertEqual(val.shortname, 'serverAuth')
662 self.assertEqual(val.longname, 'TLS Web Server Authentication')
663 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
664 self.assertIsInstance(val, ssl._ASN1Object)
665 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
666
667 val = ssl._ASN1Object.fromnid(129)
668 self.assertEqual(val, expected)
669 self.assertIsInstance(val, ssl._ASN1Object)
670 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100671 with self.assertRaisesRegex(ValueError, "unknown NID 100000"):
672 ssl._ASN1Object.fromnid(100000)
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100673 for i in range(1000):
674 try:
675 obj = ssl._ASN1Object.fromnid(i)
676 except ValueError:
677 pass
678 else:
679 self.assertIsInstance(obj.nid, int)
680 self.assertIsInstance(obj.shortname, str)
681 self.assertIsInstance(obj.longname, str)
682 self.assertIsInstance(obj.oid, (str, type(None)))
683
684 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
685 self.assertEqual(val, expected)
686 self.assertIsInstance(val, ssl._ASN1Object)
687 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
688 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
689 expected)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100690 with self.assertRaisesRegex(ValueError, "unknown object 'serverauth'"):
691 ssl._ASN1Object.fromname('serverauth')
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100692
Christian Heimes72d28502013-11-23 13:56:58 +0100693 def test_purpose_enum(self):
694 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
695 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
696 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
697 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
698 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
699 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
700 '1.3.6.1.5.5.7.3.1')
701
702 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
703 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
704 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
705 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
706 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
707 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
708 '1.3.6.1.5.5.7.3.2')
709
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100710 def test_unsupported_dtls(self):
711 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
712 self.addCleanup(s.close)
713 with self.assertRaises(NotImplementedError) as cx:
714 ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
715 self.assertEqual(str(cx.exception), "only stream sockets are supported")
716 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
717 with self.assertRaises(NotImplementedError) as cx:
718 ctx.wrap_socket(s)
719 self.assertEqual(str(cx.exception), "only stream sockets are supported")
720
Antoine Pitrouc695c952014-04-28 20:57:36 +0200721 def cert_time_ok(self, timestring, timestamp):
722 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
723
724 def cert_time_fail(self, timestring):
725 with self.assertRaises(ValueError):
726 ssl.cert_time_to_seconds(timestring)
727
728 @unittest.skipUnless(utc_offset(),
729 'local time needs to be different from UTC')
730 def test_cert_time_to_seconds_timezone(self):
731 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
732 # results if local timezone is not UTC
733 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
734 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
735
736 def test_cert_time_to_seconds(self):
737 timestring = "Jan 5 09:34:43 2018 GMT"
738 ts = 1515144883.0
739 self.cert_time_ok(timestring, ts)
740 # accept keyword parameter, assert its name
741 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
742 # accept both %e and %d (space or zero generated by strftime)
743 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
744 # case-insensitive
745 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
746 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
747 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
748 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
749 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
750 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
751 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
752 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
753
754 newyear_ts = 1230768000.0
755 # leap seconds
756 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
757 # same timestamp
758 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
759
760 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
761 # allow 60th second (even if it is not a leap second)
762 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
763 # allow 2nd leap second for compatibility with time.strptime()
764 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
765 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
766
767 # no special treatement for the special value:
768 # 99991231235959Z (rfc 5280)
769 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
770
771 @support.run_with_locale('LC_ALL', '')
772 def test_cert_time_to_seconds_locale(self):
773 # `cert_time_to_seconds()` should be locale independent
774
775 def local_february_name():
776 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
777
778 if local_february_name().lower() == 'feb':
779 self.skipTest("locale-specific month name needs to be "
780 "different from C locale")
781
782 # locale-independent
783 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
784 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
785
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100786
Antoine Pitrou152efa22010-05-16 18:19:27 +0000787class ContextTests(unittest.TestCase):
788
Antoine Pitrou23df4832010-08-04 17:14:06 +0000789 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000790 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100791 for protocol in PROTOCOLS:
792 ssl.SSLContext(protocol)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000793 self.assertRaises(TypeError, ssl.SSLContext)
794 self.assertRaises(ValueError, ssl.SSLContext, -1)
795 self.assertRaises(ValueError, ssl.SSLContext, 42)
796
Antoine Pitrou23df4832010-08-04 17:14:06 +0000797 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000798 def test_protocol(self):
799 for proto in PROTOCOLS:
800 ctx = ssl.SSLContext(proto)
801 self.assertEqual(ctx.protocol, proto)
802
803 def test_ciphers(self):
804 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
805 ctx.set_ciphers("ALL")
806 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000807 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000808 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000809
Antoine Pitrou23df4832010-08-04 17:14:06 +0000810 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000811 def test_options(self):
812 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800813 # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
Antoine Pitroub5218772010-05-21 09:56:06 +0000814 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
815 ctx.options)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800816 ctx.options |= ssl.OP_NO_TLSv1
817 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1,
818 ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000819 if can_clear_options():
820 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
821 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
822 ctx.options)
823 ctx.options = 0
Matthias Klosef7c56242016-06-12 23:40:00 -0700824 # Ubuntu has OP_NO_SSLv3 forced on by default
825 self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
Antoine Pitroub5218772010-05-21 09:56:06 +0000826 else:
827 with self.assertRaises(ValueError):
828 ctx.options = 0
829
Christian Heimes22587792013-11-21 23:56:13 +0100830 def test_verify_mode(self):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000831 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
832 # Default value
833 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
834 ctx.verify_mode = ssl.CERT_OPTIONAL
835 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
836 ctx.verify_mode = ssl.CERT_REQUIRED
837 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
838 ctx.verify_mode = ssl.CERT_NONE
839 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
840 with self.assertRaises(TypeError):
841 ctx.verify_mode = None
842 with self.assertRaises(ValueError):
843 ctx.verify_mode = 42
844
Christian Heimes2427b502013-11-23 11:24:32 +0100845 @unittest.skipUnless(have_verify_flags(),
846 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +0100847 def test_verify_flags(self):
848 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson990fcaa2015-03-04 22:49:41 -0500849 # default value
850 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
851 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +0100852 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
853 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
854 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
855 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
856 ctx.verify_flags = ssl.VERIFY_DEFAULT
857 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
858 # supports any value
859 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
860 self.assertEqual(ctx.verify_flags,
861 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
862 with self.assertRaises(TypeError):
863 ctx.verify_flags = None
864
Antoine Pitrou152efa22010-05-16 18:19:27 +0000865 def test_load_cert_chain(self):
866 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
867 # Combined key and cert in a single file
Benjamin Peterson1ea070e2014-11-03 21:05:01 -0500868 ctx.load_cert_chain(CERTFILE, keyfile=None)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000869 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
870 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200871 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000872 ctx.load_cert_chain(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000873 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000874 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000875 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000876 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000877 ctx.load_cert_chain(EMPTYCERT)
878 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000879 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000880 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
881 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
882 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000883 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000884 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000885 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000886 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000887 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000888 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
889 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000890 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000891 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Martin Panter3d81d932016-01-14 09:36:00 +0000892 ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200893 # Password protected key and cert
894 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
895 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
896 ctx.load_cert_chain(CERTFILE_PROTECTED,
897 password=bytearray(KEY_PASSWORD.encode()))
898 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
899 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
900 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
901 bytearray(KEY_PASSWORD.encode()))
902 with self.assertRaisesRegex(TypeError, "should be a string"):
903 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
904 with self.assertRaises(ssl.SSLError):
905 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
906 with self.assertRaisesRegex(ValueError, "cannot be longer"):
907 # openssl has a fixed limit on the password buffer.
908 # PEM_BUFSIZE is generally set to 1kb.
909 # Return a string larger than this.
910 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
911 # Password callback
912 def getpass_unicode():
913 return KEY_PASSWORD
914 def getpass_bytes():
915 return KEY_PASSWORD.encode()
916 def getpass_bytearray():
917 return bytearray(KEY_PASSWORD.encode())
918 def getpass_badpass():
919 return "badpass"
920 def getpass_huge():
921 return b'a' * (1024 * 1024)
922 def getpass_bad_type():
923 return 9
924 def getpass_exception():
925 raise Exception('getpass error')
926 class GetPassCallable:
927 def __call__(self):
928 return KEY_PASSWORD
929 def getpass(self):
930 return KEY_PASSWORD
931 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
932 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
933 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
934 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
935 ctx.load_cert_chain(CERTFILE_PROTECTED,
936 password=GetPassCallable().getpass)
937 with self.assertRaises(ssl.SSLError):
938 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
939 with self.assertRaisesRegex(ValueError, "cannot be longer"):
940 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
941 with self.assertRaisesRegex(TypeError, "must return a string"):
942 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
943 with self.assertRaisesRegex(Exception, "getpass error"):
944 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
945 # Make sure the password function isn't called if it isn't needed
946 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000947
948 def test_load_verify_locations(self):
949 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
950 ctx.load_verify_locations(CERTFILE)
951 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
952 ctx.load_verify_locations(BYTES_CERTFILE)
953 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
954 self.assertRaises(TypeError, ctx.load_verify_locations)
Christian Heimesefff7062013-11-21 03:35:02 +0100955 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200956 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000957 ctx.load_verify_locations(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000958 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000959 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000960 ctx.load_verify_locations(BADCERT)
961 ctx.load_verify_locations(CERTFILE, CAPATH)
962 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
963
Victor Stinner80f75e62011-01-29 11:31:20 +0000964 # Issue #10989: crash if the second argument type is invalid
965 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
966
Christian Heimesefff7062013-11-21 03:35:02 +0100967 def test_load_verify_cadata(self):
968 # test cadata
969 with open(CAFILE_CACERT) as f:
970 cacert_pem = f.read()
971 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
972 with open(CAFILE_NEURONIO) as f:
973 neuronio_pem = f.read()
974 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
975
976 # test PEM
977 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
978 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
979 ctx.load_verify_locations(cadata=cacert_pem)
980 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
981 ctx.load_verify_locations(cadata=neuronio_pem)
982 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
983 # cert already in hash table
984 ctx.load_verify_locations(cadata=neuronio_pem)
985 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
986
987 # combined
988 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
989 combined = "\n".join((cacert_pem, neuronio_pem))
990 ctx.load_verify_locations(cadata=combined)
991 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
992
993 # with junk around the certs
994 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
995 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
996 neuronio_pem, "tail"]
997 ctx.load_verify_locations(cadata="\n".join(combined))
998 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
999
1000 # test DER
1001 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1002 ctx.load_verify_locations(cadata=cacert_der)
1003 ctx.load_verify_locations(cadata=neuronio_der)
1004 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1005 # cert already in hash table
1006 ctx.load_verify_locations(cadata=cacert_der)
1007 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1008
1009 # combined
1010 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1011 combined = b"".join((cacert_der, neuronio_der))
1012 ctx.load_verify_locations(cadata=combined)
1013 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1014
1015 # error cases
1016 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1017 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
1018
1019 with self.assertRaisesRegex(ssl.SSLError, "no start line"):
1020 ctx.load_verify_locations(cadata="broken")
1021 with self.assertRaisesRegex(ssl.SSLError, "not enough data"):
1022 ctx.load_verify_locations(cadata=b"broken")
1023
1024
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001025 def test_load_dh_params(self):
1026 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1027 ctx.load_dh_params(DHFILE)
1028 if os.name != 'nt':
1029 ctx.load_dh_params(BYTES_DHFILE)
1030 self.assertRaises(TypeError, ctx.load_dh_params)
1031 self.assertRaises(TypeError, ctx.load_dh_params, None)
1032 with self.assertRaises(FileNotFoundError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001033 ctx.load_dh_params(NONEXISTINGCERT)
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001034 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001035 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001036 ctx.load_dh_params(CERTFILE)
1037
Antoine Pitroueb585ad2010-10-22 18:24:20 +00001038 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +00001039 def test_session_stats(self):
1040 for proto in PROTOCOLS:
1041 ctx = ssl.SSLContext(proto)
1042 self.assertEqual(ctx.session_stats(), {
1043 'number': 0,
1044 'connect': 0,
1045 'connect_good': 0,
1046 'connect_renegotiate': 0,
1047 'accept': 0,
1048 'accept_good': 0,
1049 'accept_renegotiate': 0,
1050 'hits': 0,
1051 'misses': 0,
1052 'timeouts': 0,
1053 'cache_full': 0,
1054 })
1055
Antoine Pitrou664c2d12010-11-17 20:29:42 +00001056 def test_set_default_verify_paths(self):
1057 # There's not much we can do to test that it acts as expected,
1058 # so just check it doesn't crash or raise an exception.
1059 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1060 ctx.set_default_verify_paths()
1061
Antoine Pitrou501da612011-12-21 09:27:41 +01001062 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +01001063 def test_set_ecdh_curve(self):
1064 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1065 ctx.set_ecdh_curve("prime256v1")
1066 ctx.set_ecdh_curve(b"prime256v1")
1067 self.assertRaises(TypeError, ctx.set_ecdh_curve)
1068 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
1069 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
1070 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
1071
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001072 @needs_sni
1073 def test_sni_callback(self):
1074 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1075
1076 # set_servername_callback expects a callable, or None
1077 self.assertRaises(TypeError, ctx.set_servername_callback)
1078 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
1079 self.assertRaises(TypeError, ctx.set_servername_callback, "")
1080 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
1081
1082 def dummycallback(sock, servername, ctx):
1083 pass
1084 ctx.set_servername_callback(None)
1085 ctx.set_servername_callback(dummycallback)
1086
1087 @needs_sni
1088 def test_sni_callback_refcycle(self):
1089 # Reference cycles through the servername callback are detected
1090 # and cleared.
1091 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1092 def dummycallback(sock, servername, ctx, cycle=ctx):
1093 pass
1094 ctx.set_servername_callback(dummycallback)
1095 wr = weakref.ref(ctx)
1096 del ctx, dummycallback
1097 gc.collect()
1098 self.assertIs(wr(), None)
1099
Christian Heimes9a5395a2013-06-17 15:44:12 +02001100 def test_cert_store_stats(self):
1101 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1102 self.assertEqual(ctx.cert_store_stats(),
1103 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1104 ctx.load_cert_chain(CERTFILE)
1105 self.assertEqual(ctx.cert_store_stats(),
1106 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1107 ctx.load_verify_locations(CERTFILE)
1108 self.assertEqual(ctx.cert_store_stats(),
1109 {'x509_ca': 0, 'crl': 0, 'x509': 1})
Martin Panterb55f8b72016-01-14 12:53:56 +00001110 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001111 self.assertEqual(ctx.cert_store_stats(),
1112 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1113
1114 def test_get_ca_certs(self):
1115 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1116 self.assertEqual(ctx.get_ca_certs(), [])
1117 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1118 ctx.load_verify_locations(CERTFILE)
1119 self.assertEqual(ctx.get_ca_certs(), [])
Martin Panterb55f8b72016-01-14 12:53:56 +00001120 # but CAFILE_CACERT is a CA cert
1121 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001122 self.assertEqual(ctx.get_ca_certs(),
1123 [{'issuer': ((('organizationName', 'Root CA'),),
1124 (('organizationalUnitName', 'http://www.cacert.org'),),
1125 (('commonName', 'CA Cert Signing Authority'),),
1126 (('emailAddress', 'support@cacert.org'),)),
1127 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1128 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1129 'serialNumber': '00',
Christian Heimesbd3a7f92013-11-21 03:40:15 +01001130 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
Christian Heimes9a5395a2013-06-17 15:44:12 +02001131 'subject': ((('organizationName', 'Root CA'),),
1132 (('organizationalUnitName', 'http://www.cacert.org'),),
1133 (('commonName', 'CA Cert Signing Authority'),),
1134 (('emailAddress', 'support@cacert.org'),)),
1135 'version': 3}])
1136
Martin Panterb55f8b72016-01-14 12:53:56 +00001137 with open(CAFILE_CACERT) as f:
Christian Heimes9a5395a2013-06-17 15:44:12 +02001138 pem = f.read()
1139 der = ssl.PEM_cert_to_DER_cert(pem)
1140 self.assertEqual(ctx.get_ca_certs(True), [der])
1141
Christian Heimes72d28502013-11-23 13:56:58 +01001142 def test_load_default_certs(self):
1143 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1144 ctx.load_default_certs()
1145
1146 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1147 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1148 ctx.load_default_certs()
1149
1150 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1151 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1152
1153 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1154 self.assertRaises(TypeError, ctx.load_default_certs, None)
1155 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1156
Benjamin Peterson91244e02014-10-03 18:17:15 -04001157 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Benjamin Peterson5915b0f2014-10-03 17:27:05 -04001158 def test_load_default_certs_env(self):
1159 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1160 with support.EnvironmentVarGuard() as env:
1161 env["SSL_CERT_DIR"] = CAPATH
1162 env["SSL_CERT_FILE"] = CERTFILE
1163 ctx.load_default_certs()
1164 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1165
Benjamin Peterson91244e02014-10-03 18:17:15 -04001166 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
1167 def test_load_default_certs_env_windows(self):
1168 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1169 ctx.load_default_certs()
1170 stats = ctx.cert_store_stats()
1171
1172 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1173 with support.EnvironmentVarGuard() as env:
1174 env["SSL_CERT_DIR"] = CAPATH
1175 env["SSL_CERT_FILE"] = CERTFILE
1176 ctx.load_default_certs()
1177 stats["x509"] += 1
1178 self.assertEqual(ctx.cert_store_stats(), stats)
1179
Christian Heimes4c05b472013-11-23 15:58:30 +01001180 def test_create_default_context(self):
1181 ctx = ssl.create_default_context()
Donald Stufft6a2ba942014-03-23 19:05:28 -04001182 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001183 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001184 self.assertTrue(ctx.check_hostname)
Christian Heimes4c05b472013-11-23 15:58:30 +01001185 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001186 self.assertEqual(
1187 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1188 getattr(ssl, "OP_NO_COMPRESSION", 0),
1189 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001190
1191 with open(SIGNING_CA) as f:
1192 cadata = f.read()
1193 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1194 cadata=cadata)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001195 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001196 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1197 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001198 self.assertEqual(
1199 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1200 getattr(ssl, "OP_NO_COMPRESSION", 0),
1201 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001202
1203 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001204 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001205 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1206 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001207 self.assertEqual(
1208 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1209 getattr(ssl, "OP_NO_COMPRESSION", 0),
1210 )
1211 self.assertEqual(
1212 ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0),
1213 getattr(ssl, "OP_SINGLE_DH_USE", 0),
1214 )
1215 self.assertEqual(
1216 ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1217 getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1218 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001219
Christian Heimes67986f92013-11-23 22:43:47 +01001220 def test__create_stdlib_context(self):
1221 ctx = ssl._create_stdlib_context()
1222 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1223 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001224 self.assertFalse(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001225 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1226
1227 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1228 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1229 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1230 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1231
1232 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001233 cert_reqs=ssl.CERT_REQUIRED,
1234 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001235 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1236 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001237 self.assertTrue(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001238 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1239
1240 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1241 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1242 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1243 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Christian Heimes4c05b472013-11-23 15:58:30 +01001244
Christian Heimes1aa9a752013-12-02 02:41:19 +01001245 def test_check_hostname(self):
1246 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1247 self.assertFalse(ctx.check_hostname)
1248
1249 # Requires CERT_REQUIRED or CERT_OPTIONAL
1250 with self.assertRaises(ValueError):
1251 ctx.check_hostname = True
1252 ctx.verify_mode = ssl.CERT_REQUIRED
1253 self.assertFalse(ctx.check_hostname)
1254 ctx.check_hostname = True
1255 self.assertTrue(ctx.check_hostname)
1256
1257 ctx.verify_mode = ssl.CERT_OPTIONAL
1258 ctx.check_hostname = True
1259 self.assertTrue(ctx.check_hostname)
1260
1261 # Cannot set CERT_NONE with check_hostname enabled
1262 with self.assertRaises(ValueError):
1263 ctx.verify_mode = ssl.CERT_NONE
1264 ctx.check_hostname = False
1265 self.assertFalse(ctx.check_hostname)
1266
Antoine Pitrou152efa22010-05-16 18:19:27 +00001267
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001268class SSLErrorTests(unittest.TestCase):
1269
1270 def test_str(self):
1271 # The str() of a SSLError doesn't include the errno
1272 e = ssl.SSLError(1, "foo")
1273 self.assertEqual(str(e), "foo")
1274 self.assertEqual(e.errno, 1)
1275 # Same for a subclass
1276 e = ssl.SSLZeroReturnError(1, "foo")
1277 self.assertEqual(str(e), "foo")
1278 self.assertEqual(e.errno, 1)
1279
1280 def test_lib_reason(self):
1281 # Test the library and reason attributes
1282 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1283 with self.assertRaises(ssl.SSLError) as cm:
1284 ctx.load_dh_params(CERTFILE)
1285 self.assertEqual(cm.exception.library, 'PEM')
1286 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1287 s = str(cm.exception)
1288 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1289
1290 def test_subclass(self):
1291 # Check that the appropriate SSLError subclass is raised
1292 # (this only tests one of them)
1293 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1294 with socket.socket() as s:
1295 s.bind(("127.0.0.1", 0))
Charles-François Natali6e204602014-07-23 19:28:13 +01001296 s.listen()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001297 c = socket.socket()
1298 c.connect(s.getsockname())
1299 c.setblocking(False)
1300 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001301 with self.assertRaises(ssl.SSLWantReadError) as cm:
1302 c.do_handshake()
1303 s = str(cm.exception)
1304 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1305 # For compatibility
1306 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1307
1308
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001309class MemoryBIOTests(unittest.TestCase):
1310
1311 def test_read_write(self):
1312 bio = ssl.MemoryBIO()
1313 bio.write(b'foo')
1314 self.assertEqual(bio.read(), b'foo')
1315 self.assertEqual(bio.read(), b'')
1316 bio.write(b'foo')
1317 bio.write(b'bar')
1318 self.assertEqual(bio.read(), b'foobar')
1319 self.assertEqual(bio.read(), b'')
1320 bio.write(b'baz')
1321 self.assertEqual(bio.read(2), b'ba')
1322 self.assertEqual(bio.read(1), b'z')
1323 self.assertEqual(bio.read(1), b'')
1324
1325 def test_eof(self):
1326 bio = ssl.MemoryBIO()
1327 self.assertFalse(bio.eof)
1328 self.assertEqual(bio.read(), b'')
1329 self.assertFalse(bio.eof)
1330 bio.write(b'foo')
1331 self.assertFalse(bio.eof)
1332 bio.write_eof()
1333 self.assertFalse(bio.eof)
1334 self.assertEqual(bio.read(2), b'fo')
1335 self.assertFalse(bio.eof)
1336 self.assertEqual(bio.read(1), b'o')
1337 self.assertTrue(bio.eof)
1338 self.assertEqual(bio.read(), b'')
1339 self.assertTrue(bio.eof)
1340
1341 def test_pending(self):
1342 bio = ssl.MemoryBIO()
1343 self.assertEqual(bio.pending, 0)
1344 bio.write(b'foo')
1345 self.assertEqual(bio.pending, 3)
1346 for i in range(3):
1347 bio.read(1)
1348 self.assertEqual(bio.pending, 3-i-1)
1349 for i in range(3):
1350 bio.write(b'x')
1351 self.assertEqual(bio.pending, i+1)
1352 bio.read()
1353 self.assertEqual(bio.pending, 0)
1354
1355 def test_buffer_types(self):
1356 bio = ssl.MemoryBIO()
1357 bio.write(b'foo')
1358 self.assertEqual(bio.read(), b'foo')
1359 bio.write(bytearray(b'bar'))
1360 self.assertEqual(bio.read(), b'bar')
1361 bio.write(memoryview(b'baz'))
1362 self.assertEqual(bio.read(), b'baz')
1363
1364 def test_error_types(self):
1365 bio = ssl.MemoryBIO()
1366 self.assertRaises(TypeError, bio.write, 'foo')
1367 self.assertRaises(TypeError, bio.write, None)
1368 self.assertRaises(TypeError, bio.write, True)
1369 self.assertRaises(TypeError, bio.write, 1)
1370
1371
Bill Janssen6e027db2007-11-15 22:23:56 +00001372class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001373
Antoine Pitrou480a1242010-04-28 21:37:09 +00001374 def test_connect(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001375 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001376 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1377 cert_reqs=ssl.CERT_NONE)
1378 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001379 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001380 self.assertEqual({}, s.getpeercert())
1381 finally:
1382 s.close()
1383
1384 # this should fail because we have no verification certs
1385 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1386 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001387 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Martin Panter3d81d932016-01-14 09:36:00 +00001388 s.connect, (REMOTE_HOST, 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001389 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001390
Antoine Pitrou350c7222010-09-09 13:31:46 +00001391 # this should succeed because we specify the root cert
1392 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1393 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001394 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001395 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001396 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001397 self.assertTrue(s.getpeercert())
1398 finally:
1399 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001400
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001401 def test_connect_ex(self):
1402 # Issue #11326: check connect_ex() implementation
Martin Panter3d81d932016-01-14 09:36:00 +00001403 with support.transient_internet(REMOTE_HOST):
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001404 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1405 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001406 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001407 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001408 self.assertEqual(0, s.connect_ex((REMOTE_HOST, 443)))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001409 self.assertTrue(s.getpeercert())
1410 finally:
1411 s.close()
1412
1413 def test_non_blocking_connect_ex(self):
1414 # Issue #11326: non-blocking connect_ex() should allow handshake
1415 # to proceed after the socket gets ready.
Martin Panter3d81d932016-01-14 09:36:00 +00001416 with support.transient_internet(REMOTE_HOST):
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001417 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1418 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001419 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001420 do_handshake_on_connect=False)
1421 try:
1422 s.setblocking(False)
Martin Panter3d81d932016-01-14 09:36:00 +00001423 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +00001424 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1425 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001426 # Wait for connect to finish
1427 select.select([], [s], [], 5.0)
1428 # Non-blocking handshake
1429 while True:
1430 try:
1431 s.do_handshake()
1432 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001433 except ssl.SSLWantReadError:
1434 select.select([s], [], [], 5.0)
1435 except ssl.SSLWantWriteError:
1436 select.select([], [s], [], 5.0)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001437 # SSL established
1438 self.assertTrue(s.getpeercert())
1439 finally:
1440 s.close()
1441
Antoine Pitroub4410db2011-05-18 18:51:06 +02001442 def test_timeout_connect_ex(self):
1443 # Issue #12065: on a timeout, connect_ex() should return the original
1444 # errno (mimicking the behaviour of non-SSL sockets).
Martin Panter3d81d932016-01-14 09:36:00 +00001445 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub4410db2011-05-18 18:51:06 +02001446 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1447 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001448 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitroub4410db2011-05-18 18:51:06 +02001449 do_handshake_on_connect=False)
1450 try:
1451 s.settimeout(0.0000001)
Martin Panter3d81d932016-01-14 09:36:00 +00001452 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitroub4410db2011-05-18 18:51:06 +02001453 if rc == 0:
Martin Panter3d81d932016-01-14 09:36:00 +00001454 self.skipTest("REMOTE_HOST responded too quickly")
Antoine Pitroub4410db2011-05-18 18:51:06 +02001455 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1456 finally:
1457 s.close()
1458
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001459 def test_connect_ex_error(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001460 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001461 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1462 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001463 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001464 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001465 rc = s.connect_ex((REMOTE_HOST, 444))
Christian Heimesde570742013-12-16 21:15:44 +01001466 # Issue #19919: Windows machines or VMs hosted on Windows
1467 # machines sometimes return EWOULDBLOCK.
Martin Panter73f55072016-01-14 12:21:02 +00001468 errors = (
Martin Panterfab75d92016-01-15 02:08:13 +00001469 errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
Martin Panter73f55072016-01-14 12:21:02 +00001470 errno.EWOULDBLOCK,
1471 )
1472 self.assertIn(rc, errors)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001473 finally:
1474 s.close()
1475
Antoine Pitrou152efa22010-05-16 18:19:27 +00001476 def test_connect_with_context(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001477 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001478 # Same as test_connect, but with a separately created context
1479 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1480 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001481 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001482 try:
1483 self.assertEqual({}, s.getpeercert())
1484 finally:
1485 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +00001486 # Same with a server hostname
1487 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3d81d932016-01-14 09:36:00 +00001488 server_hostname=REMOTE_HOST)
Martin Panter514bb072016-01-14 12:46:49 +00001489 s.connect((REMOTE_HOST, 443))
Benjamin Peterson7243b572014-11-23 17:04:34 -06001490 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +00001491 # This should fail because we have no verification certs
1492 ctx.verify_mode = ssl.CERT_REQUIRED
1493 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +00001494 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Martin Panter3d81d932016-01-14 09:36:00 +00001495 s.connect, (REMOTE_HOST, 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001496 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +00001497 # This should succeed because we specify the root cert
Martin Panter3d81d932016-01-14 09:36:00 +00001498 ctx.load_verify_locations(REMOTE_ROOT_CERT)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001499 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001500 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001501 try:
1502 cert = s.getpeercert()
1503 self.assertTrue(cert)
1504 finally:
1505 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001506
1507 def test_connect_capath(self):
1508 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001509 # NOTE: the subject hashing algorithm has been changed between
1510 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1511 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001512 # filename) for this test to be portable across OpenSSL releases.
Martin Panter3d81d932016-01-14 09:36:00 +00001513 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001514 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1515 ctx.verify_mode = ssl.CERT_REQUIRED
1516 ctx.load_verify_locations(capath=CAPATH)
1517 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001518 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001519 try:
1520 cert = s.getpeercert()
1521 self.assertTrue(cert)
1522 finally:
1523 s.close()
1524 # Same with a bytes `capath` argument
1525 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1526 ctx.verify_mode = ssl.CERT_REQUIRED
1527 ctx.load_verify_locations(capath=BYTES_CAPATH)
1528 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001529 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001530 try:
1531 cert = s.getpeercert()
1532 self.assertTrue(cert)
1533 finally:
1534 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001535
Christian Heimesefff7062013-11-21 03:35:02 +01001536 def test_connect_cadata(self):
Martin Panterb55f8b72016-01-14 12:53:56 +00001537 with open(REMOTE_ROOT_CERT) as f:
Christian Heimesefff7062013-11-21 03:35:02 +01001538 pem = f.read()
1539 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panterb55f8b72016-01-14 12:53:56 +00001540 with support.transient_internet(REMOTE_HOST):
Christian Heimesefff7062013-11-21 03:35:02 +01001541 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1542 ctx.verify_mode = ssl.CERT_REQUIRED
1543 ctx.load_verify_locations(cadata=pem)
1544 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
Martin Panterb55f8b72016-01-14 12:53:56 +00001545 s.connect((REMOTE_HOST, 443))
Christian Heimesefff7062013-11-21 03:35:02 +01001546 cert = s.getpeercert()
1547 self.assertTrue(cert)
1548
1549 # same with DER
1550 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1551 ctx.verify_mode = ssl.CERT_REQUIRED
1552 ctx.load_verify_locations(cadata=der)
1553 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
Martin Panterb55f8b72016-01-14 12:53:56 +00001554 s.connect((REMOTE_HOST, 443))
Christian Heimesefff7062013-11-21 03:35:02 +01001555 cert = s.getpeercert()
1556 self.assertTrue(cert)
1557
Antoine Pitroue3220242010-04-24 11:13:53 +00001558 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1559 def test_makefile_close(self):
1560 # Issue #5238: creating a file-like object with makefile() shouldn't
1561 # delay closing the underlying "real socket" (here tested with its
1562 # file descriptor, hence skipping the test under Windows).
Martin Panter3d81d932016-01-14 09:36:00 +00001563 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001564 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001565 ss.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001566 fd = ss.fileno()
1567 f = ss.makefile()
1568 f.close()
1569 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +00001570 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001571 # Closing the SSL socket should close the fd too
1572 ss.close()
1573 gc.collect()
1574 with self.assertRaises(OSError) as e:
1575 os.read(fd, 0)
1576 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001577
Antoine Pitrou480a1242010-04-28 21:37:09 +00001578 def test_non_blocking_handshake(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001579 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001580 s = socket.socket(socket.AF_INET)
Martin Panter3d81d932016-01-14 09:36:00 +00001581 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001582 s.setblocking(False)
1583 s = ssl.wrap_socket(s,
1584 cert_reqs=ssl.CERT_NONE,
1585 do_handshake_on_connect=False)
1586 count = 0
1587 while True:
1588 try:
1589 count += 1
1590 s.do_handshake()
1591 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001592 except ssl.SSLWantReadError:
1593 select.select([s], [], [])
1594 except ssl.SSLWantWriteError:
1595 select.select([], [s], [])
Antoine Pitrou350c7222010-09-09 13:31:46 +00001596 s.close()
1597 if support.verbose:
1598 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001599
Antoine Pitrou480a1242010-04-28 21:37:09 +00001600 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +02001601 def _test_get_server_certificate(host, port, cert=None):
1602 with support.transient_internet(host):
Antoine Pitrou94a5b662014-04-16 18:56:28 +02001603 pem = ssl.get_server_certificate((host, port))
Antoine Pitrou15399c32011-04-28 19:23:55 +02001604 if not pem:
1605 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001606
Antoine Pitrou15399c32011-04-28 19:23:55 +02001607 try:
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001608 pem = ssl.get_server_certificate((host, port),
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001609 ca_certs=CERTFILE)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001610 except ssl.SSLError as x:
1611 #should fail
1612 if support.verbose:
1613 sys.stdout.write("%s\n" % x)
1614 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001615 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1616
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001617 pem = ssl.get_server_certificate((host, port),
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001618 ca_certs=cert)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001619 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001620 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001621 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001622 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001623
Martin Panter73f55072016-01-14 12:21:02 +00001624 _test_get_server_certificate(REMOTE_HOST, 443, REMOTE_ROOT_CERT)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001625 if support.IPV6_ENABLED:
1626 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001627
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001628 def test_ciphers(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001629 remote = (REMOTE_HOST, 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001630 with support.transient_internet(remote[0]):
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001631 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1632 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1633 s.connect(remote)
1634 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1635 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1636 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001637 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +00001638 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +00001639 with socket.socket(socket.AF_INET) as sock:
1640 s = ssl.wrap_socket(sock,
1641 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1642 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001643
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001644 def test_algorithms(self):
1645 # Issue #8484: all algorithms should be available when verifying a
1646 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +00001647 # SHA256 was added in OpenSSL 0.9.8
1648 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1649 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001650 # sha256.tbs-internet.com needs SNI to use the correct certificate
1651 if not ssl.HAS_SNI:
1652 self.skipTest("SNI needed for this test")
Victor Stinnerf332abb2011-01-08 03:16:05 +00001653 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1654 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001655 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +00001656 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001657 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1658 ctx.verify_mode = ssl.CERT_REQUIRED
1659 ctx.load_verify_locations(sha256_cert)
1660 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1661 server_hostname="sha256.tbs-internet.com")
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001662 try:
1663 s.connect(remote)
1664 if support.verbose:
1665 sys.stdout.write("\nCipher with %r is %r\n" %
1666 (remote, s.cipher()))
1667 sys.stdout.write("Certificate is:\n%s\n" %
1668 pprint.pformat(s.getpeercert()))
1669 finally:
1670 s.close()
1671
Christian Heimes9a5395a2013-06-17 15:44:12 +02001672 def test_get_ca_certs_capath(self):
1673 # capath certs are loaded on request
Martin Panterb55f8b72016-01-14 12:53:56 +00001674 with support.transient_internet(REMOTE_HOST):
Christian Heimes9a5395a2013-06-17 15:44:12 +02001675 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1676 ctx.verify_mode = ssl.CERT_REQUIRED
1677 ctx.load_verify_locations(capath=CAPATH)
1678 self.assertEqual(ctx.get_ca_certs(), [])
1679 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panterb55f8b72016-01-14 12:53:56 +00001680 s.connect((REMOTE_HOST, 443))
Christian Heimes9a5395a2013-06-17 15:44:12 +02001681 try:
1682 cert = s.getpeercert()
1683 self.assertTrue(cert)
1684 finally:
1685 s.close()
1686 self.assertEqual(len(ctx.get_ca_certs()), 1)
1687
Christian Heimes575596e2013-12-15 21:49:17 +01001688 @needs_sni
Christian Heimes8e7f3942013-12-05 07:41:08 +01001689 def test_context_setget(self):
1690 # Check that the context of a connected socket can be replaced.
Martin Panterb55f8b72016-01-14 12:53:56 +00001691 with support.transient_internet(REMOTE_HOST):
Christian Heimes8e7f3942013-12-05 07:41:08 +01001692 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1693 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1694 s = socket.socket(socket.AF_INET)
1695 with ctx1.wrap_socket(s) as ss:
Martin Panterb55f8b72016-01-14 12:53:56 +00001696 ss.connect((REMOTE_HOST, 443))
Christian Heimes8e7f3942013-12-05 07:41:08 +01001697 self.assertIs(ss.context, ctx1)
1698 self.assertIs(ss._sslobj.context, ctx1)
1699 ss.context = ctx2
1700 self.assertIs(ss.context, ctx2)
1701 self.assertIs(ss._sslobj.context, ctx2)
1702
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001703
1704class NetworkedBIOTests(unittest.TestCase):
1705
1706 def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs):
1707 # A simple IO loop. Call func(*args) depending on the error we get
1708 # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs.
1709 timeout = kwargs.get('timeout', 10)
1710 count = 0
1711 while True:
1712 errno = None
1713 count += 1
1714 try:
1715 ret = func(*args)
1716 except ssl.SSLError as e:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001717 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
Martin Panter40b97ec2016-01-14 13:05:46 +00001718 ssl.SSL_ERROR_WANT_WRITE):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001719 raise
1720 errno = e.errno
1721 # Get any data from the outgoing BIO irrespective of any error, and
1722 # send it to the socket.
1723 buf = outgoing.read()
1724 sock.sendall(buf)
1725 # If there's no error, we're done. For WANT_READ, we need to get
1726 # data from the socket and put it in the incoming BIO.
1727 if errno is None:
1728 break
1729 elif errno == ssl.SSL_ERROR_WANT_READ:
1730 buf = sock.recv(32768)
1731 if buf:
1732 incoming.write(buf)
1733 else:
1734 incoming.write_eof()
1735 if support.verbose:
1736 sys.stdout.write("Needed %d calls to complete %s().\n"
1737 % (count, func.__name__))
1738 return ret
1739
1740 def test_handshake(self):
Martin Panter40b97ec2016-01-14 13:05:46 +00001741 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001742 sock = socket.socket(socket.AF_INET)
Martin Panter40b97ec2016-01-14 13:05:46 +00001743 sock.connect((REMOTE_HOST, 443))
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001744 incoming = ssl.MemoryBIO()
1745 outgoing = ssl.MemoryBIO()
1746 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1747 ctx.verify_mode = ssl.CERT_REQUIRED
Martin Panter40b97ec2016-01-14 13:05:46 +00001748 ctx.load_verify_locations(REMOTE_ROOT_CERT)
Benjamin Petersonf9284ae2014-11-23 17:06:39 -06001749 ctx.check_hostname = True
Martin Panter40b97ec2016-01-14 13:05:46 +00001750 sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001751 self.assertIs(sslobj._sslobj.owner, sslobj)
1752 self.assertIsNone(sslobj.cipher())
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001753 self.assertIsNone(sslobj.shared_ciphers())
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001754 self.assertRaises(ValueError, sslobj.getpeercert)
1755 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1756 self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
1757 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1758 self.assertTrue(sslobj.cipher())
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001759 self.assertIsNone(sslobj.shared_ciphers())
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001760 self.assertTrue(sslobj.getpeercert())
1761 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1762 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
Martin Panter40b97ec2016-01-14 13:05:46 +00001763 try:
1764 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
1765 except ssl.SSLSyscallError:
1766 # self-signed.pythontest.net probably shuts down the TCP
1767 # connection without sending a secure shutdown message, and
1768 # this is reported as SSL_ERROR_SYSCALL
1769 pass
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001770 self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
1771 sock.close()
1772
1773 def test_read_write_data(self):
Martin Panter40b97ec2016-01-14 13:05:46 +00001774 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001775 sock = socket.socket(socket.AF_INET)
Martin Panter40b97ec2016-01-14 13:05:46 +00001776 sock.connect((REMOTE_HOST, 443))
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001777 incoming = ssl.MemoryBIO()
1778 outgoing = ssl.MemoryBIO()
1779 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1780 ctx.verify_mode = ssl.CERT_NONE
1781 sslobj = ctx.wrap_bio(incoming, outgoing, False)
1782 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1783 req = b'GET / HTTP/1.0\r\n\r\n'
1784 self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req)
1785 buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024)
1786 self.assertEqual(buf[:5], b'HTTP/')
1787 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
1788 sock.close()
1789
1790
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001791try:
1792 import threading
1793except ImportError:
1794 _have_threads = False
1795else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001796 _have_threads = True
1797
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001798 from test.ssl_servers import make_https_server
1799
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001800 class ThreadedEchoServer(threading.Thread):
1801
1802 class ConnectionHandler(threading.Thread):
1803
1804 """A mildly complicated class, because we want it to work both
1805 with and without the SSL wrapper around the socket connection, so
1806 that we can test the STARTTLS functionality."""
1807
Bill Janssen6e027db2007-11-15 22:23:56 +00001808 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001809 self.server = server
1810 self.running = False
1811 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001812 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001813 self.sock.setblocking(1)
1814 self.sslconn = None
1815 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001816 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001817
Antoine Pitrou480a1242010-04-28 21:37:09 +00001818 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001819 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001820 self.sslconn = self.server.context.wrap_socket(
1821 self.sock, server_side=True)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001822 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1823 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001824 except (ssl.SSLError, ConnectionResetError) as e:
1825 # We treat ConnectionResetError as though it were an
1826 # SSLError - OpenSSL on Ubuntu abruptly closes the
1827 # connection when asked to use an unsupported protocol.
1828 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001829 # XXX Various errors can have happened here, for example
1830 # a mismatching protocol version, an invalid certificate,
1831 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001832 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001833 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001834 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001835 self.running = False
1836 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001837 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001838 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001839 else:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001840 self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
Antoine Pitroub5218772010-05-21 09:56:06 +00001841 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001842 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001843 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001844 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1845 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001846 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001847 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1848 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001849 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001850 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001851 sys.stdout.write(" server: selected protocol is now "
1852 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001853 return True
1854
1855 def read(self):
1856 if self.sslconn:
1857 return self.sslconn.read()
1858 else:
1859 return self.sock.recv(1024)
1860
1861 def write(self, bytes):
1862 if self.sslconn:
1863 return self.sslconn.write(bytes)
1864 else:
1865 return self.sock.send(bytes)
1866
1867 def close(self):
1868 if self.sslconn:
1869 self.sslconn.close()
1870 else:
1871 self.sock.close()
1872
Antoine Pitrou480a1242010-04-28 21:37:09 +00001873 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001874 self.running = True
1875 if not self.server.starttls_server:
1876 if not self.wrap_conn():
1877 return
1878 while self.running:
1879 try:
1880 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001881 stripped = msg.strip()
1882 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001883 # eof, so quit this handler
1884 self.running = False
1885 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001886 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001887 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001888 sys.stdout.write(" server: client closed connection\n")
1889 self.close()
1890 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001891 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001892 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001893 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001894 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001895 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001896 if not self.wrap_conn():
1897 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001898 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001899 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001900 if support.verbose and self.server.connectionchatty:
1901 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001902 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001903 self.sock = self.sslconn.unwrap()
1904 self.sslconn = None
1905 if support.verbose and self.server.connectionchatty:
1906 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001907 elif stripped == b'CB tls-unique':
1908 if support.verbose and self.server.connectionchatty:
1909 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1910 data = self.sslconn.get_channel_binding("tls-unique")
1911 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001912 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001913 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001914 self.server.connectionchatty):
1915 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001916 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1917 % (msg, ctype, msg.lower(), ctype))
1918 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001919 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001920 if self.server.chatty:
1921 handle_error("Test server failure:\n")
1922 self.close()
1923 self.running = False
1924 # normally, we'd just stop here, but for the test
1925 # harness, we want to stop the server
1926 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001927
Antoine Pitroub5218772010-05-21 09:56:06 +00001928 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001929 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001930 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersoncca27322015-01-23 16:35:37 -05001931 npn_protocols=None, alpn_protocols=None,
1932 ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00001933 if context:
1934 self.context = context
1935 else:
1936 self.context = ssl.SSLContext(ssl_version
1937 if ssl_version is not None
1938 else ssl.PROTOCOL_TLSv1)
1939 self.context.verify_mode = (certreqs if certreqs is not None
1940 else ssl.CERT_NONE)
1941 if cacerts:
1942 self.context.load_verify_locations(cacerts)
1943 if certificate:
1944 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001945 if npn_protocols:
1946 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001947 if alpn_protocols:
1948 self.context.set_alpn_protocols(alpn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00001949 if ciphers:
1950 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001951 self.chatty = chatty
1952 self.connectionchatty = connectionchatty
1953 self.starttls_server = starttls_server
1954 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001955 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001956 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001957 self.active = False
Benjamin Petersoncca27322015-01-23 16:35:37 -05001958 self.selected_npn_protocols = []
1959 self.selected_alpn_protocols = []
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001960 self.shared_ciphers = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001961 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001962 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001963 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001964
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001965 def __enter__(self):
1966 self.start(threading.Event())
1967 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001968 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001969
1970 def __exit__(self, *args):
1971 self.stop()
1972 self.join()
1973
Antoine Pitrou480a1242010-04-28 21:37:09 +00001974 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001975 self.flag = flag
1976 threading.Thread.start(self)
1977
Antoine Pitrou480a1242010-04-28 21:37:09 +00001978 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00001979 self.sock.settimeout(0.05)
Charles-François Natali6e204602014-07-23 19:28:13 +01001980 self.sock.listen()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001981 self.active = True
1982 if self.flag:
1983 # signal an event
1984 self.flag.set()
1985 while self.active:
1986 try:
1987 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001988 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001989 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00001990 + repr(connaddr) + '\n')
1991 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001992 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01001993 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001994 except socket.timeout:
1995 pass
1996 except KeyboardInterrupt:
1997 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001998 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001999
Antoine Pitrou480a1242010-04-28 21:37:09 +00002000 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002001 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002002
Bill Janssen54cc54c2007-12-14 22:08:56 +00002003 class AsyncoreEchoServer(threading.Thread):
2004
2005 # this one's based on asyncore.dispatcher
2006
2007 class EchoServer (asyncore.dispatcher):
2008
2009 class ConnectionHandler (asyncore.dispatcher_with_send):
2010
2011 def __init__(self, conn, certfile):
2012 self.socket = ssl.wrap_socket(conn, server_side=True,
2013 certfile=certfile,
2014 do_handshake_on_connect=False)
2015 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002016 self._ssl_accepting = True
2017 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002018
2019 def readable(self):
2020 if isinstance(self.socket, ssl.SSLSocket):
2021 while self.socket.pending() > 0:
2022 self.handle_read_event()
2023 return True
2024
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002025 def _do_ssl_handshake(self):
2026 try:
2027 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02002028 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
2029 return
2030 except ssl.SSLEOFError:
2031 return self.handle_close()
2032 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002033 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002034 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002035 if err.args[0] == errno.ECONNABORTED:
2036 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002037 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002038 self._ssl_accepting = False
2039
2040 def handle_read(self):
2041 if self._ssl_accepting:
2042 self._do_ssl_handshake()
2043 else:
2044 data = self.recv(1024)
2045 if support.verbose:
2046 sys.stdout.write(" server: read %s from client\n" % repr(data))
2047 if not data:
2048 self.close()
2049 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002050 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00002051
2052 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00002053 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002054 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002055 sys.stdout.write(" server: closed connection %s\n" % self.socket)
2056
2057 def handle_error(self):
2058 raise
2059
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002060 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002061 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002062 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2063 self.port = support.bind_port(sock, '')
2064 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00002065 self.listen(5)
2066
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00002067 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002068 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002069 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
2070 self.ConnectionHandler(sock_obj, self.certfile)
2071
2072 def handle_error(self):
2073 raise
2074
Trent Nelson78520002008-04-10 20:54:35 +00002075 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002076 self.flag = None
2077 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002078 self.server = self.EchoServer(certfile)
2079 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00002080 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002081 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00002082
2083 def __str__(self):
2084 return "<%s %s>" % (self.__class__.__name__, self.server)
2085
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002086 def __enter__(self):
2087 self.start(threading.Event())
2088 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002089 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002090
2091 def __exit__(self, *args):
2092 if support.verbose:
2093 sys.stdout.write(" cleanup: stopping server.\n")
2094 self.stop()
2095 if support.verbose:
2096 sys.stdout.write(" cleanup: joining server thread.\n")
2097 self.join()
2098 if support.verbose:
2099 sys.stdout.write(" cleanup: successfully joined.\n")
2100
Bill Janssen54cc54c2007-12-14 22:08:56 +00002101 def start (self, flag=None):
2102 self.flag = flag
2103 threading.Thread.start(self)
2104
Antoine Pitrou480a1242010-04-28 21:37:09 +00002105 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002106 self.active = True
2107 if self.flag:
2108 self.flag.set()
2109 while self.active:
2110 try:
2111 asyncore.loop(1)
2112 except:
2113 pass
2114
Antoine Pitrou480a1242010-04-28 21:37:09 +00002115 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002116 self.active = False
2117 self.server.close()
2118
Antoine Pitroub5218772010-05-21 09:56:06 +00002119 def server_params_test(client_context, server_context, indata=b"FOO\n",
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002120 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00002121 """
2122 Launch a server, connect a client to it and try various reads
2123 and writes.
2124 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002125 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00002126 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002127 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00002128 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002129 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002130 with client_context.wrap_socket(socket.socket(),
2131 server_hostname=sni_name) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002132 s.connect((HOST, server.port))
2133 for arg in [indata, bytearray(indata), memoryview(indata)]:
2134 if connectionchatty:
2135 if support.verbose:
2136 sys.stdout.write(
2137 " client: sending %r...\n" % indata)
2138 s.write(arg)
2139 outdata = s.read()
2140 if connectionchatty:
2141 if support.verbose:
2142 sys.stdout.write(" client: read %r\n" % outdata)
2143 if outdata != indata.lower():
2144 raise AssertionError(
2145 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2146 % (outdata[:20], len(outdata),
2147 indata[:20].lower(), len(indata)))
2148 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00002149 if connectionchatty:
2150 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002151 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002152 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01002153 'compression': s.compression(),
2154 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002155 'peercert': s.getpeercert(),
Benjamin Petersoncca27322015-01-23 16:35:37 -05002156 'client_alpn_protocol': s.selected_alpn_protocol(),
Antoine Pitrou47e40422014-09-04 21:00:10 +02002157 'client_npn_protocol': s.selected_npn_protocol(),
2158 'version': s.version(),
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002159 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01002160 s.close()
Benjamin Petersoncca27322015-01-23 16:35:37 -05002161 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2162 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002163 stats['server_shared_ciphers'] = server.shared_ciphers
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002164 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00002165
Antoine Pitroub5218772010-05-21 09:56:06 +00002166 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2167 certsreqs=None, server_options=0, client_options=0):
Antoine Pitrou47e40422014-09-04 21:00:10 +02002168 """
2169 Try to SSL-connect using *client_protocol* to *server_protocol*.
2170 If *expect_success* is true, assert that the connection succeeds,
2171 if it's false, assert that the connection fails.
2172 Also, if *expect_success* is a string, assert that it is the protocol
2173 version actually used by the connection.
2174 """
Benjamin Peterson2a691a82008-03-31 01:51:45 +00002175 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002176 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00002177 certtype = {
2178 ssl.CERT_NONE: "CERT_NONE",
2179 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2180 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2181 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002182 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002183 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002184 sys.stdout.write(formatstr %
2185 (ssl.get_protocol_name(client_protocol),
2186 ssl.get_protocol_name(server_protocol),
2187 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00002188 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002189 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00002190 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002191 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002192
2193 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2194 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2195 # starting from OpenSSL 1.0.0 (see issue #8322).
2196 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2197 client_context.set_ciphers("ALL")
2198
Antoine Pitroub5218772010-05-21 09:56:06 +00002199 for ctx in (client_context, server_context):
2200 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00002201 ctx.load_cert_chain(CERTFILE)
2202 ctx.load_verify_locations(CERTFILE)
2203 try:
Antoine Pitrou47e40422014-09-04 21:00:10 +02002204 stats = server_params_test(client_context, server_context,
2205 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002206 # Protocol mismatch can result in either an SSLError, or a
2207 # "Connection reset by peer" error.
2208 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002209 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002210 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002211 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002212 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002213 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002214 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002215 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00002216 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002217 "Client protocol %s succeeded with server protocol %s!"
2218 % (ssl.get_protocol_name(client_protocol),
2219 ssl.get_protocol_name(server_protocol)))
Antoine Pitrou47e40422014-09-04 21:00:10 +02002220 elif (expect_success is not True
2221 and expect_success != stats['version']):
2222 raise AssertionError("version mismatch: expected %r, got %r"
2223 % (expect_success, stats['version']))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002224
2225
Bill Janssen6e027db2007-11-15 22:23:56 +00002226 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002227
Antoine Pitrou23df4832010-08-04 17:14:06 +00002228 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002229 def test_echo(self):
2230 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002231 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002232 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002233 for protocol in PROTOCOLS:
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01002234 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
2235 context = ssl.SSLContext(protocol)
2236 context.load_cert_chain(CERTFILE)
2237 server_params_test(context, context,
2238 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002239
Antoine Pitrou480a1242010-04-28 21:37:09 +00002240 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002241 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002242 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002243 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2244 context.verify_mode = ssl.CERT_REQUIRED
2245 context.load_verify_locations(CERTFILE)
2246 context.load_cert_chain(CERTFILE)
2247 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002248 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02002249 s = context.wrap_socket(socket.socket(),
2250 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002251 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02002252 # getpeercert() raise ValueError while the handshake isn't
2253 # done.
2254 with self.assertRaises(ValueError):
2255 s.getpeercert()
2256 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002257 cert = s.getpeercert()
2258 self.assertTrue(cert, "Can't get peer certificate.")
2259 cipher = s.cipher()
2260 if support.verbose:
2261 sys.stdout.write(pprint.pformat(cert) + '\n')
2262 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2263 if 'subject' not in cert:
2264 self.fail("No subject field in certificate: %s." %
2265 pprint.pformat(cert))
2266 if ((('organizationName', 'Python Software Foundation'),)
2267 not in cert['subject']):
2268 self.fail(
2269 "Missing or invalid 'organizationName' field in certificate subject; "
2270 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00002271 self.assertIn('notBefore', cert)
2272 self.assertIn('notAfter', cert)
2273 before = ssl.cert_time_to_seconds(cert['notBefore'])
2274 after = ssl.cert_time_to_seconds(cert['notAfter'])
2275 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002276 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002277
Christian Heimes2427b502013-11-23 11:24:32 +01002278 @unittest.skipUnless(have_verify_flags(),
2279 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01002280 def test_crl_check(self):
2281 if support.verbose:
2282 sys.stdout.write("\n")
2283
2284 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2285 server_context.load_cert_chain(SIGNED_CERTFILE)
2286
2287 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2288 context.verify_mode = ssl.CERT_REQUIRED
2289 context.load_verify_locations(SIGNING_CA)
Benjamin Petersonc3d9c5c2015-03-04 23:18:48 -05002290 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2291 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +01002292
2293 # VERIFY_DEFAULT should pass
2294 server = ThreadedEchoServer(context=server_context, chatty=True)
2295 with server:
2296 with context.wrap_socket(socket.socket()) as s:
2297 s.connect((HOST, server.port))
2298 cert = s.getpeercert()
2299 self.assertTrue(cert, "Can't get peer certificate.")
2300
2301 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01002302 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01002303
2304 server = ThreadedEchoServer(context=server_context, chatty=True)
2305 with server:
2306 with context.wrap_socket(socket.socket()) as s:
2307 with self.assertRaisesRegex(ssl.SSLError,
2308 "certificate verify failed"):
2309 s.connect((HOST, server.port))
2310
2311 # now load a CRL file. The CRL file is signed by the CA.
2312 context.load_verify_locations(CRLFILE)
2313
2314 server = ThreadedEchoServer(context=server_context, chatty=True)
2315 with server:
2316 with context.wrap_socket(socket.socket()) as s:
2317 s.connect((HOST, server.port))
2318 cert = s.getpeercert()
2319 self.assertTrue(cert, "Can't get peer certificate.")
2320
Christian Heimes1aa9a752013-12-02 02:41:19 +01002321 def test_check_hostname(self):
2322 if support.verbose:
2323 sys.stdout.write("\n")
2324
2325 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2326 server_context.load_cert_chain(SIGNED_CERTFILE)
2327
2328 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2329 context.verify_mode = ssl.CERT_REQUIRED
2330 context.check_hostname = True
2331 context.load_verify_locations(SIGNING_CA)
2332
2333 # correct hostname should verify
2334 server = ThreadedEchoServer(context=server_context, chatty=True)
2335 with server:
2336 with context.wrap_socket(socket.socket(),
2337 server_hostname="localhost") as s:
2338 s.connect((HOST, server.port))
2339 cert = s.getpeercert()
2340 self.assertTrue(cert, "Can't get peer certificate.")
2341
2342 # incorrect hostname should raise an exception
2343 server = ThreadedEchoServer(context=server_context, chatty=True)
2344 with server:
2345 with context.wrap_socket(socket.socket(),
2346 server_hostname="invalid") as s:
2347 with self.assertRaisesRegex(ssl.CertificateError,
2348 "hostname 'invalid' doesn't match 'localhost'"):
2349 s.connect((HOST, server.port))
2350
2351 # missing server_hostname arg should cause an exception, too
2352 server = ThreadedEchoServer(context=server_context, chatty=True)
2353 with server:
2354 with socket.socket() as s:
2355 with self.assertRaisesRegex(ValueError,
2356 "check_hostname requires server_hostname"):
2357 context.wrap_socket(s)
2358
Martin Panter407b62f2016-01-30 03:41:43 +00002359 def test_wrong_cert(self):
Martin Panter3464ea22016-02-01 21:58:11 +00002360 """Connecting when the server rejects the client's certificate
2361
2362 Launch a server with CERT_REQUIRED, and check that trying to
2363 connect to it with a wrong client certificate fails.
2364 """
2365 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2366 "wrongcert.pem")
2367 server = ThreadedEchoServer(CERTFILE,
2368 certreqs=ssl.CERT_REQUIRED,
2369 cacerts=CERTFILE, chatty=False,
2370 connectionchatty=False)
2371 with server, \
2372 socket.socket() as sock, \
2373 ssl.wrap_socket(sock,
2374 certfile=certfile,
2375 ssl_version=ssl.PROTOCOL_TLSv1) as s:
2376 try:
2377 # Expect either an SSL error about the server rejecting
2378 # the connection, or a low-level connection reset (which
2379 # sometimes happens on Windows)
2380 s.connect((HOST, server.port))
2381 except ssl.SSLError as e:
2382 if support.verbose:
2383 sys.stdout.write("\nSSLError is %r\n" % e)
2384 except OSError as e:
2385 if e.errno != errno.ECONNRESET:
2386 raise
2387 if support.verbose:
2388 sys.stdout.write("\nsocket.error is %r\n" % e)
2389 else:
2390 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002391
Antoine Pitrou480a1242010-04-28 21:37:09 +00002392 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002393 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002394 in the client when attempting handshake.
2395 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002396 listener_ready = threading.Event()
2397 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002398
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002399 s = socket.socket()
2400 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002401
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002402 # `listener` runs in a thread. It sits in an accept() until
2403 # the main thread connects. Then it rudely closes the socket,
2404 # and sets Event `listener_gone` to let the main thread know
2405 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002406 def listener():
Charles-François Natali6e204602014-07-23 19:28:13 +01002407 s.listen()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002408 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002409 newsock, addr = s.accept()
2410 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002411 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002412 listener_gone.set()
2413
2414 def connector():
2415 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002416 with socket.socket() as c:
2417 c.connect((HOST, port))
2418 listener_gone.wait()
2419 try:
2420 ssl_sock = ssl.wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002421 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002422 pass
2423 else:
2424 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002425
2426 t = threading.Thread(target=listener)
2427 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002428 try:
2429 connector()
2430 finally:
2431 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002432
Antoine Pitrou23df4832010-08-04 17:14:06 +00002433 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002434 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2435 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002436 def test_protocol_sslv2(self):
2437 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002438 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002439 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002440 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2441 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2442 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002443 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Victor Stinner648b8622014-12-12 12:23:59 +01002444 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2445 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002446 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002447 # SSLv23 client with specific SSL options
2448 if no_sslv2_implies_sslv3_hello():
2449 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2450 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2451 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002452 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002453 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002454 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002455 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002456
Antoine Pitrou23df4832010-08-04 17:14:06 +00002457 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002458 def test_protocol_sslv23(self):
2459 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002460 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002461 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002462 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2463 try:
2464 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002465 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002466 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2467 if support.verbose:
2468 sys.stdout.write(
2469 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2470 % str(x))
Benjamin Petersone32467c2014-12-05 21:59:35 -05002471 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002472 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002473 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002474 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002475
Benjamin Petersone32467c2014-12-05 21:59:35 -05002476 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002477 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002478 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002479 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002480
Benjamin Petersone32467c2014-12-05 21:59:35 -05002481 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002482 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002483 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002484 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002485
Antoine Pitroub5218772010-05-21 09:56:06 +00002486 # Server with specific SSL options
Benjamin Petersone32467c2014-12-05 21:59:35 -05002487 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2488 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002489 server_options=ssl.OP_NO_SSLv3)
2490 # Will choose TLSv1
2491 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2492 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2493 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2494 server_options=ssl.OP_NO_TLSv1)
2495
2496
Antoine Pitrou23df4832010-08-04 17:14:06 +00002497 @skip_if_broken_ubuntu_ssl
Benjamin Petersone32467c2014-12-05 21:59:35 -05002498 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2499 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002500 def test_protocol_sslv3(self):
2501 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002502 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002503 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002504 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2505 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2506 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002507 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2508 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002509 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2510 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002511 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002512 if no_sslv2_implies_sslv3_hello():
2513 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002514 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2515 False, client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002516
Antoine Pitrou23df4832010-08-04 17:14:06 +00002517 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002518 def test_protocol_tlsv1(self):
2519 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002520 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002521 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002522 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2523 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2524 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002525 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2526 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002527 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2528 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002529 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2530 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002531
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002532 @skip_if_broken_ubuntu_ssl
2533 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2534 "TLS version 1.1 not supported.")
2535 def test_protocol_tlsv1_1(self):
2536 """Connecting to a TLSv1.1 server with various client options.
2537 Testing against older TLS versions."""
2538 if support.verbose:
2539 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002540 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002541 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2542 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002543 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2544 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002545 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2546 client_options=ssl.OP_NO_TLSv1_1)
2547
Antoine Pitrou47e40422014-09-04 21:00:10 +02002548 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002549 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2550 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2551
2552
2553 @skip_if_broken_ubuntu_ssl
2554 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2555 "TLS version 1.2 not supported.")
2556 def test_protocol_tlsv1_2(self):
2557 """Connecting to a TLSv1.2 server with various client options.
2558 Testing against older TLS versions."""
2559 if support.verbose:
2560 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002561 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002562 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2563 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2564 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2565 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002566 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2567 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002568 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2569 client_options=ssl.OP_NO_TLSv1_2)
2570
Antoine Pitrou47e40422014-09-04 21:00:10 +02002571 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002572 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2573 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2574 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2575 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2576
Antoine Pitrou480a1242010-04-28 21:37:09 +00002577 def test_starttls(self):
2578 """Switching from clear text to encrypted and back again."""
2579 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 +00002580
Trent Nelson78520002008-04-10 20:54:35 +00002581 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002582 ssl_version=ssl.PROTOCOL_TLSv1,
2583 starttls_server=True,
2584 chatty=True,
2585 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002586 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002587 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002588 s = socket.socket()
2589 s.setblocking(1)
2590 s.connect((HOST, server.port))
2591 if support.verbose:
2592 sys.stdout.write("\n")
2593 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002594 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002595 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002596 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002597 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002598 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002599 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002600 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002601 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002602 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002603 msg = outdata.strip().lower()
2604 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2605 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002606 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002607 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002608 " client: read %r from server, starting TLS...\n"
2609 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002610 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
2611 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002612 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2613 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002614 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002615 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002616 " client: read %r from server, ending TLS...\n"
2617 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002618 s = conn.unwrap()
2619 wrapped = False
2620 else:
2621 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002622 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002623 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002624 if support.verbose:
2625 sys.stdout.write(" client: closing connection.\n")
2626 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002627 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002628 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002629 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002630 if wrapped:
2631 conn.close()
2632 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002633 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002634
Antoine Pitrou480a1242010-04-28 21:37:09 +00002635 def test_socketserver(self):
2636 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002637 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002638 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002639 if support.verbose:
2640 sys.stdout.write('\n')
2641 with open(CERTFILE, 'rb') as f:
2642 d1 = f.read()
2643 d2 = ''
2644 # now fetch the same data from the HTTPS server
Benjamin Peterson4ffb0752014-11-03 14:29:33 -05002645 url = 'https://localhost:%d/%s' % (
2646 server.port, os.path.split(CERTFILE)[1])
2647 context = ssl.create_default_context(cafile=CERTFILE)
2648 f = urllib.request.urlopen(url, context=context)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002649 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002650 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002651 if dlen and (int(dlen) > 0):
2652 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002653 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002654 sys.stdout.write(
2655 " client: read %d bytes from remote server '%s'\n"
2656 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002657 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002658 f.close()
2659 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002660
Antoine Pitrou480a1242010-04-28 21:37:09 +00002661 def test_asyncore_server(self):
2662 """Check the example asyncore integration."""
2663 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00002664
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002665 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002666 sys.stdout.write("\n")
2667
Antoine Pitrou480a1242010-04-28 21:37:09 +00002668 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002669 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002670 with server:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002671 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002672 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002673 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002674 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002675 " client: sending %r...\n" % indata)
2676 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002677 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002678 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002679 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002680 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002681 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002682 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2683 % (outdata[:20], len(outdata),
2684 indata[:20].lower(), len(indata)))
2685 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002686 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002687 sys.stdout.write(" client: closing connection.\n")
2688 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002689 if support.verbose:
2690 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002691
Antoine Pitrou480a1242010-04-28 21:37:09 +00002692 def test_recv_send(self):
2693 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002694 if support.verbose:
2695 sys.stdout.write("\n")
2696
2697 server = ThreadedEchoServer(CERTFILE,
2698 certreqs=ssl.CERT_NONE,
2699 ssl_version=ssl.PROTOCOL_TLSv1,
2700 cacerts=CERTFILE,
2701 chatty=True,
2702 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002703 with server:
2704 s = ssl.wrap_socket(socket.socket(),
2705 server_side=False,
2706 certfile=CERTFILE,
2707 ca_certs=CERTFILE,
2708 cert_reqs=ssl.CERT_NONE,
2709 ssl_version=ssl.PROTOCOL_TLSv1)
2710 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002711 # helper methods for standardising recv* method signatures
2712 def _recv_into():
2713 b = bytearray(b"\0"*100)
2714 count = s.recv_into(b)
2715 return b[:count]
2716
2717 def _recvfrom_into():
2718 b = bytearray(b"\0"*100)
2719 count, addr = s.recvfrom_into(b)
2720 return b[:count]
2721
2722 # (name, method, whether to expect success, *args)
2723 send_methods = [
2724 ('send', s.send, True, []),
2725 ('sendto', s.sendto, False, ["some.address"]),
2726 ('sendall', s.sendall, True, []),
2727 ]
2728 recv_methods = [
2729 ('recv', s.recv, True, []),
2730 ('recvfrom', s.recvfrom, False, ["some.address"]),
2731 ('recv_into', _recv_into, True, []),
2732 ('recvfrom_into', _recvfrom_into, False, []),
2733 ]
2734 data_prefix = "PREFIX_"
2735
2736 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002737 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002738 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002739 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002740 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002741 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002742 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002743 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002744 "<<{outdata:r}>> ({nout:d}) received; "
2745 "expected <<{indata:r}>> ({nin:d})\n".format(
2746 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002747 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002748 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002749 )
2750 )
2751 except ValueError as e:
2752 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002753 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002754 "Failed to send with method <<{name:s}>>; "
2755 "expected to succeed.\n".format(name=meth_name)
2756 )
2757 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002758 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002759 "Method <<{name:s}>> failed with unexpected "
2760 "exception message: {exp:s}\n".format(
2761 name=meth_name, exp=e
2762 )
2763 )
2764
2765 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002766 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002767 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002768 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002769 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002770 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002771 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002772 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002773 "<<{outdata:r}>> ({nout:d}) received; "
2774 "expected <<{indata:r}>> ({nin:d})\n".format(
2775 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002776 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002777 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002778 )
2779 )
2780 except ValueError as e:
2781 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002782 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002783 "Failed to receive with method <<{name:s}>>; "
2784 "expected to succeed.\n".format(name=meth_name)
2785 )
2786 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002787 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002788 "Method <<{name:s}>> failed with unexpected "
2789 "exception message: {exp:s}\n".format(
2790 name=meth_name, exp=e
2791 )
2792 )
2793 # consume data
2794 s.read()
2795
Martin Panterf6b1d662016-03-28 00:22:09 +00002796 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panterbed7f1a2016-07-11 00:17:13 +00002797 data = b"data"
Martin Panter5503d472016-03-27 05:35:19 +00002798 s.send(data)
2799 buffer = bytearray(len(data))
2800 self.assertEqual(s.read(-1, buffer), len(data))
2801 self.assertEqual(buffer, data)
2802
Nick Coghlan513886a2011-08-28 00:00:27 +10002803 # Make sure sendmsg et al are disallowed to avoid
2804 # inadvertent disclosure of data and/or corruption
2805 # of the encrypted data stream
2806 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2807 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2808 self.assertRaises(NotImplementedError,
2809 s.recvmsg_into, bytearray(100))
2810
Antoine Pitrou480a1242010-04-28 21:37:09 +00002811 s.write(b"over\n")
Martin Panter5503d472016-03-27 05:35:19 +00002812
2813 self.assertRaises(ValueError, s.recv, -1)
2814 self.assertRaises(ValueError, s.read, -1)
2815
Bill Janssen58afe4c2008-09-08 16:45:19 +00002816 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002817
Martin Panterbed7f1a2016-07-11 00:17:13 +00002818 def test_recv_zero(self):
2819 server = ThreadedEchoServer(CERTFILE)
2820 server.__enter__()
2821 self.addCleanup(server.__exit__, None, None)
2822 s = socket.create_connection((HOST, server.port))
2823 self.addCleanup(s.close)
2824 s = ssl.wrap_socket(s, suppress_ragged_eofs=False)
2825 self.addCleanup(s.close)
2826
2827 # recv/read(0) should return no data
2828 s.send(b"data")
2829 self.assertEqual(s.recv(0), b"")
2830 self.assertEqual(s.read(0), b"")
2831 self.assertEqual(s.read(), b"data")
2832
2833 # Should not block if the other end sends no data
2834 s.setblocking(False)
2835 self.assertEqual(s.recv(0), b"")
2836 self.assertEqual(s.recv_into(bytearray()), 0)
2837
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002838 def test_nonblocking_send(self):
2839 server = ThreadedEchoServer(CERTFILE,
2840 certreqs=ssl.CERT_NONE,
2841 ssl_version=ssl.PROTOCOL_TLSv1,
2842 cacerts=CERTFILE,
2843 chatty=True,
2844 connectionchatty=False)
2845 with server:
2846 s = ssl.wrap_socket(socket.socket(),
2847 server_side=False,
2848 certfile=CERTFILE,
2849 ca_certs=CERTFILE,
2850 cert_reqs=ssl.CERT_NONE,
2851 ssl_version=ssl.PROTOCOL_TLSv1)
2852 s.connect((HOST, server.port))
2853 s.setblocking(False)
2854
2855 # If we keep sending data, at some point the buffers
2856 # will be full and the call will block
2857 buf = bytearray(8192)
2858 def fill_buffer():
2859 while True:
2860 s.send(buf)
2861 self.assertRaises((ssl.SSLWantWriteError,
2862 ssl.SSLWantReadError), fill_buffer)
2863
2864 # Now read all the output and discard it
2865 s.setblocking(True)
2866 s.close()
2867
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002868 def test_handshake_timeout(self):
2869 # Issue #5103: SSL handshake must respect the socket timeout
2870 server = socket.socket(socket.AF_INET)
2871 host = "127.0.0.1"
2872 port = support.bind_port(server)
2873 started = threading.Event()
2874 finish = False
2875
2876 def serve():
Charles-François Natali6e204602014-07-23 19:28:13 +01002877 server.listen()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002878 started.set()
2879 conns = []
2880 while not finish:
2881 r, w, e = select.select([server], [], [], 0.1)
2882 if server in r:
2883 # Let the socket hang around rather than having
2884 # it closed by garbage collection.
2885 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00002886 for sock in conns:
2887 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002888
2889 t = threading.Thread(target=serve)
2890 t.start()
2891 started.wait()
2892
2893 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00002894 try:
2895 c = socket.socket(socket.AF_INET)
2896 c.settimeout(0.2)
2897 c.connect((host, port))
2898 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002899 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002900 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00002901 finally:
2902 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002903 try:
2904 c = socket.socket(socket.AF_INET)
2905 c = ssl.wrap_socket(c)
2906 c.settimeout(0.2)
2907 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002908 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002909 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002910 finally:
2911 c.close()
2912 finally:
2913 finish = True
2914 t.join()
2915 server.close()
2916
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002917 def test_server_accept(self):
2918 # Issue #16357: accept() on a SSLSocket created through
2919 # SSLContext.wrap_socket().
2920 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2921 context.verify_mode = ssl.CERT_REQUIRED
2922 context.load_verify_locations(CERTFILE)
2923 context.load_cert_chain(CERTFILE)
2924 server = socket.socket(socket.AF_INET)
2925 host = "127.0.0.1"
2926 port = support.bind_port(server)
2927 server = context.wrap_socket(server, server_side=True)
2928
2929 evt = threading.Event()
2930 remote = None
2931 peer = None
2932 def serve():
2933 nonlocal remote, peer
Charles-François Natali6e204602014-07-23 19:28:13 +01002934 server.listen()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002935 # Block on the accept and wait on the connection to close.
2936 evt.set()
2937 remote, peer = server.accept()
2938 remote.recv(1)
2939
2940 t = threading.Thread(target=serve)
2941 t.start()
2942 # Client wait until server setup and perform a connect.
2943 evt.wait()
2944 client = context.wrap_socket(socket.socket())
2945 client.connect((host, port))
2946 client_addr = client.getsockname()
2947 client.close()
2948 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002949 remote.close()
2950 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002951 # Sanity checks.
2952 self.assertIsInstance(remote, ssl.SSLSocket)
2953 self.assertEqual(peer, client_addr)
2954
Antoine Pitrou242db722013-05-01 20:52:07 +02002955 def test_getpeercert_enotconn(self):
2956 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2957 with context.wrap_socket(socket.socket()) as sock:
2958 with self.assertRaises(OSError) as cm:
2959 sock.getpeercert()
2960 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2961
2962 def test_do_handshake_enotconn(self):
2963 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2964 with context.wrap_socket(socket.socket()) as sock:
2965 with self.assertRaises(OSError) as cm:
2966 sock.do_handshake()
2967 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2968
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002969 def test_default_ciphers(self):
2970 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2971 try:
2972 # Force a set of weak ciphers on our client context
2973 context.set_ciphers("DES")
2974 except ssl.SSLError:
2975 self.skipTest("no DES cipher available")
2976 with ThreadedEchoServer(CERTFILE,
2977 ssl_version=ssl.PROTOCOL_SSLv23,
2978 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002979 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02002980 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002981 s.connect((HOST, server.port))
2982 self.assertIn("no shared cipher", str(server.conn_errors[0]))
2983
Antoine Pitrou47e40422014-09-04 21:00:10 +02002984 def test_version_basic(self):
2985 """
2986 Basic tests for SSLSocket.version().
2987 More tests are done in the test_protocol_*() methods.
2988 """
2989 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2990 with ThreadedEchoServer(CERTFILE,
2991 ssl_version=ssl.PROTOCOL_TLSv1,
2992 chatty=False) as server:
2993 with context.wrap_socket(socket.socket()) as s:
2994 self.assertIs(s.version(), None)
2995 s.connect((HOST, server.port))
2996 self.assertEqual(s.version(), "TLSv1")
2997 self.assertIs(s.version(), None)
2998
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01002999 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
3000 def test_default_ecdh_curve(self):
3001 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
3002 # should be enabled by default on SSL contexts.
3003 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3004 context.load_cert_chain(CERTFILE)
Antoine Pitrouc0430612014-04-16 18:33:39 +02003005 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
3006 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
3007 # our default cipher list should prefer ECDH-based ciphers
3008 # automatically.
3009 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
3010 context.set_ciphers("ECCdraft:ECDH")
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003011 with ThreadedEchoServer(context=context) as server:
3012 with context.wrap_socket(socket.socket()) as s:
3013 s.connect((HOST, server.port))
3014 self.assertIn("ECDH", s.cipher()[0])
3015
Antoine Pitroud6494802011-07-21 01:11:30 +02003016 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
3017 "'tls-unique' channel binding not available")
3018 def test_tls_unique_channel_binding(self):
3019 """Test tls-unique channel binding."""
3020 if support.verbose:
3021 sys.stdout.write("\n")
3022
3023 server = ThreadedEchoServer(CERTFILE,
3024 certreqs=ssl.CERT_NONE,
3025 ssl_version=ssl.PROTOCOL_TLSv1,
3026 cacerts=CERTFILE,
3027 chatty=True,
3028 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003029 with server:
3030 s = ssl.wrap_socket(socket.socket(),
3031 server_side=False,
3032 certfile=CERTFILE,
3033 ca_certs=CERTFILE,
3034 cert_reqs=ssl.CERT_NONE,
3035 ssl_version=ssl.PROTOCOL_TLSv1)
3036 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02003037 # get the data
3038 cb_data = s.get_channel_binding("tls-unique")
3039 if support.verbose:
3040 sys.stdout.write(" got channel binding data: {0!r}\n"
3041 .format(cb_data))
3042
3043 # check if it is sane
3044 self.assertIsNotNone(cb_data)
3045 self.assertEqual(len(cb_data), 12) # True for TLSv1
3046
3047 # and compare with the peers version
3048 s.write(b"CB tls-unique\n")
3049 peer_data_repr = s.read().strip()
3050 self.assertEqual(peer_data_repr,
3051 repr(cb_data).encode("us-ascii"))
3052 s.close()
3053
3054 # now, again
3055 s = ssl.wrap_socket(socket.socket(),
3056 server_side=False,
3057 certfile=CERTFILE,
3058 ca_certs=CERTFILE,
3059 cert_reqs=ssl.CERT_NONE,
3060 ssl_version=ssl.PROTOCOL_TLSv1)
3061 s.connect((HOST, server.port))
3062 new_cb_data = s.get_channel_binding("tls-unique")
3063 if support.verbose:
3064 sys.stdout.write(" got another channel binding data: {0!r}\n"
3065 .format(new_cb_data))
3066 # is it really unique
3067 self.assertNotEqual(cb_data, new_cb_data)
3068 self.assertIsNotNone(cb_data)
3069 self.assertEqual(len(cb_data), 12) # True for TLSv1
3070 s.write(b"CB tls-unique\n")
3071 peer_data_repr = s.read().strip()
3072 self.assertEqual(peer_data_repr,
3073 repr(new_cb_data).encode("us-ascii"))
3074 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00003075
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003076 def test_compression(self):
3077 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3078 context.load_cert_chain(CERTFILE)
3079 stats = server_params_test(context, context,
3080 chatty=True, connectionchatty=True)
3081 if support.verbose:
3082 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
3083 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
3084
3085 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
3086 "ssl.OP_NO_COMPRESSION needed for this test")
3087 def test_compression_disabled(self):
3088 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3089 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01003090 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003091 stats = server_params_test(context, context,
3092 chatty=True, connectionchatty=True)
3093 self.assertIs(stats['compression'], None)
3094
Antoine Pitrou0e576f12011-12-22 10:03:38 +01003095 def test_dh_params(self):
3096 # Check we can get a connection with ephemeral Diffie-Hellman
3097 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3098 context.load_cert_chain(CERTFILE)
3099 context.load_dh_params(DHFILE)
3100 context.set_ciphers("kEDH")
3101 stats = server_params_test(context, context,
3102 chatty=True, connectionchatty=True)
3103 cipher = stats["cipher"][0]
3104 parts = cipher.split("-")
3105 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
3106 self.fail("Non-DH cipher: " + cipher[0])
3107
Benjamin Petersoncca27322015-01-23 16:35:37 -05003108 def test_selected_alpn_protocol(self):
3109 # selected_alpn_protocol() is None unless ALPN is used.
3110 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3111 context.load_cert_chain(CERTFILE)
3112 stats = server_params_test(context, context,
3113 chatty=True, connectionchatty=True)
3114 self.assertIs(stats['client_alpn_protocol'], None)
3115
3116 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
3117 def test_selected_alpn_protocol_if_server_uses_alpn(self):
3118 # selected_alpn_protocol() is None unless ALPN is used by the client.
3119 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3120 client_context.load_verify_locations(CERTFILE)
3121 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3122 server_context.load_cert_chain(CERTFILE)
3123 server_context.set_alpn_protocols(['foo', 'bar'])
3124 stats = server_params_test(client_context, server_context,
3125 chatty=True, connectionchatty=True)
3126 self.assertIs(stats['client_alpn_protocol'], None)
3127
3128 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
3129 def test_alpn_protocols(self):
3130 server_protocols = ['foo', 'bar', 'milkshake']
3131 protocol_tests = [
3132 (['foo', 'bar'], 'foo'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003133 (['bar', 'foo'], 'foo'),
Benjamin Petersoncca27322015-01-23 16:35:37 -05003134 (['milkshake'], 'milkshake'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003135 (['http/3.0', 'http/4.0'], None)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003136 ]
3137 for client_protocols, expected in protocol_tests:
3138 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3139 server_context.load_cert_chain(CERTFILE)
3140 server_context.set_alpn_protocols(server_protocols)
3141 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3142 client_context.load_cert_chain(CERTFILE)
3143 client_context.set_alpn_protocols(client_protocols)
3144 stats = server_params_test(client_context, server_context,
3145 chatty=True, connectionchatty=True)
3146
3147 msg = "failed trying %s (s) and %s (c).\n" \
3148 "was expecting %s, but got %%s from the %%s" \
3149 % (str(server_protocols), str(client_protocols),
3150 str(expected))
3151 client_result = stats['client_alpn_protocol']
3152 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3153 server_result = stats['server_alpn_protocols'][-1] \
3154 if len(stats['server_alpn_protocols']) else 'nothing'
3155 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3156
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01003157 def test_selected_npn_protocol(self):
3158 # selected_npn_protocol() is None unless NPN is used
3159 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3160 context.load_cert_chain(CERTFILE)
3161 stats = server_params_test(context, context,
3162 chatty=True, connectionchatty=True)
3163 self.assertIs(stats['client_npn_protocol'], None)
3164
3165 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
3166 def test_npn_protocols(self):
3167 server_protocols = ['http/1.1', 'spdy/2']
3168 protocol_tests = [
3169 (['http/1.1', 'spdy/2'], 'http/1.1'),
3170 (['spdy/2', 'http/1.1'], 'http/1.1'),
3171 (['spdy/2', 'test'], 'spdy/2'),
3172 (['abc', 'def'], 'abc')
3173 ]
3174 for client_protocols, expected in protocol_tests:
3175 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3176 server_context.load_cert_chain(CERTFILE)
3177 server_context.set_npn_protocols(server_protocols)
3178 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3179 client_context.load_cert_chain(CERTFILE)
3180 client_context.set_npn_protocols(client_protocols)
3181 stats = server_params_test(client_context, server_context,
3182 chatty=True, connectionchatty=True)
3183
3184 msg = "failed trying %s (s) and %s (c).\n" \
3185 "was expecting %s, but got %%s from the %%s" \
3186 % (str(server_protocols), str(client_protocols),
3187 str(expected))
3188 client_result = stats['client_npn_protocol']
3189 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3190 server_result = stats['server_npn_protocols'][-1] \
3191 if len(stats['server_npn_protocols']) else 'nothing'
3192 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3193
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003194 def sni_contexts(self):
3195 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3196 server_context.load_cert_chain(SIGNED_CERTFILE)
3197 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3198 other_context.load_cert_chain(SIGNED_CERTFILE2)
3199 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3200 client_context.verify_mode = ssl.CERT_REQUIRED
3201 client_context.load_verify_locations(SIGNING_CA)
3202 return server_context, other_context, client_context
3203
3204 def check_common_name(self, stats, name):
3205 cert = stats['peercert']
3206 self.assertIn((('commonName', name),), cert['subject'])
3207
3208 @needs_sni
3209 def test_sni_callback(self):
3210 calls = []
3211 server_context, other_context, client_context = self.sni_contexts()
3212
3213 def servername_cb(ssl_sock, server_name, initial_context):
3214 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003215 if server_name is not None:
3216 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003217 server_context.set_servername_callback(servername_cb)
3218
3219 stats = server_params_test(client_context, server_context,
3220 chatty=True,
3221 sni_name='supermessage')
3222 # The hostname was fetched properly, and the certificate was
3223 # changed for the connection.
3224 self.assertEqual(calls, [("supermessage", server_context)])
3225 # CERTFILE4 was selected
3226 self.check_common_name(stats, 'fakehostname')
3227
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003228 calls = []
3229 # The callback is called with server_name=None
3230 stats = server_params_test(client_context, server_context,
3231 chatty=True,
3232 sni_name=None)
3233 self.assertEqual(calls, [(None, server_context)])
3234 self.check_common_name(stats, 'localhost')
3235
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003236 # Check disabling the callback
3237 calls = []
3238 server_context.set_servername_callback(None)
3239
3240 stats = server_params_test(client_context, server_context,
3241 chatty=True,
3242 sni_name='notfunny')
3243 # Certificate didn't change
3244 self.check_common_name(stats, 'localhost')
3245 self.assertEqual(calls, [])
3246
3247 @needs_sni
3248 def test_sni_callback_alert(self):
3249 # Returning a TLS alert is reflected to the connecting client
3250 server_context, other_context, client_context = self.sni_contexts()
3251
3252 def cb_returning_alert(ssl_sock, server_name, initial_context):
3253 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3254 server_context.set_servername_callback(cb_returning_alert)
3255
3256 with self.assertRaises(ssl.SSLError) as cm:
3257 stats = server_params_test(client_context, server_context,
3258 chatty=False,
3259 sni_name='supermessage')
3260 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3261
3262 @needs_sni
3263 def test_sni_callback_raising(self):
3264 # Raising fails the connection with a TLS handshake failure alert.
3265 server_context, other_context, client_context = self.sni_contexts()
3266
3267 def cb_raising(ssl_sock, server_name, initial_context):
3268 1/0
3269 server_context.set_servername_callback(cb_raising)
3270
3271 with self.assertRaises(ssl.SSLError) as cm, \
3272 support.captured_stderr() as stderr:
3273 stats = server_params_test(client_context, server_context,
3274 chatty=False,
3275 sni_name='supermessage')
3276 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3277 self.assertIn("ZeroDivisionError", stderr.getvalue())
3278
3279 @needs_sni
3280 def test_sni_callback_wrong_return_type(self):
3281 # Returning the wrong return type terminates the TLS connection
3282 # with an internal error alert.
3283 server_context, other_context, client_context = self.sni_contexts()
3284
3285 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3286 return "foo"
3287 server_context.set_servername_callback(cb_wrong_return_type)
3288
3289 with self.assertRaises(ssl.SSLError) as cm, \
3290 support.captured_stderr() as stderr:
3291 stats = server_params_test(client_context, server_context,
3292 chatty=False,
3293 sni_name='supermessage')
3294 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3295 self.assertIn("TypeError", stderr.getvalue())
3296
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003297 def test_shared_ciphers(self):
Benjamin Petersonaacd5242015-01-07 11:42:38 -06003298 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson15042922015-01-07 22:12:43 -06003299 server_context.load_cert_chain(SIGNED_CERTFILE)
3300 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3301 client_context.verify_mode = ssl.CERT_REQUIRED
3302 client_context.load_verify_locations(SIGNING_CA)
Benjamin Peterson23ef9fa2015-01-07 21:21:34 -06003303 client_context.set_ciphers("RC4")
Benjamin Petersone6838e02015-01-07 20:52:40 -06003304 server_context.set_ciphers("AES:RC4")
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003305 stats = server_params_test(client_context, server_context)
3306 ciphers = stats['server_shared_ciphers'][0]
3307 self.assertGreater(len(ciphers), 0)
3308 for name, tls_version, bits in ciphers:
Benjamin Peterson23ef9fa2015-01-07 21:21:34 -06003309 self.assertIn("RC4", name.split("-"))
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003310
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003311 def test_read_write_after_close_raises_valuerror(self):
3312 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3313 context.verify_mode = ssl.CERT_REQUIRED
3314 context.load_verify_locations(CERTFILE)
3315 context.load_cert_chain(CERTFILE)
3316 server = ThreadedEchoServer(context=context, chatty=False)
3317
3318 with server:
3319 s = context.wrap_socket(socket.socket())
3320 s.connect((HOST, server.port))
3321 s.close()
3322
3323 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02003324 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003325
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02003326 def test_sendfile(self):
3327 TEST_DATA = b"x" * 512
3328 with open(support.TESTFN, 'wb') as f:
3329 f.write(TEST_DATA)
3330 self.addCleanup(support.unlink, support.TESTFN)
3331 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3332 context.verify_mode = ssl.CERT_REQUIRED
3333 context.load_verify_locations(CERTFILE)
3334 context.load_cert_chain(CERTFILE)
3335 server = ThreadedEchoServer(context=context, chatty=False)
3336 with server:
3337 with context.wrap_socket(socket.socket()) as s:
3338 s.connect((HOST, server.port))
3339 with open(support.TESTFN, 'rb') as file:
3340 s.sendfile(file)
3341 self.assertEqual(s.recv(1024), TEST_DATA)
3342
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003343
Thomas Woutersed03b412007-08-28 21:37:11 +00003344def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00003345 if support.verbose:
Berker Peksag9e7990a2015-05-16 23:21:26 +03003346 import warnings
Antoine Pitrou15cee622010-08-04 16:45:21 +00003347 plats = {
3348 'Linux': platform.linux_distribution,
3349 'Mac': platform.mac_ver,
3350 'Windows': platform.win32_ver,
3351 }
Berker Peksag9e7990a2015-05-16 23:21:26 +03003352 with warnings.catch_warnings():
3353 warnings.filterwarnings(
3354 'ignore',
3355 'dist\(\) and linux_distribution\(\) '
3356 'functions are deprecated .*',
3357 PendingDeprecationWarning,
3358 )
3359 for name, func in plats.items():
3360 plat = func()
3361 if plat and plat[0]:
3362 plat = '%s %r' % (name, plat)
3363 break
3364 else:
3365 plat = repr(platform.platform())
Antoine Pitrou15cee622010-08-04 16:45:21 +00003366 print("test_ssl: testing with %r %r" %
3367 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3368 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00003369 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01003370 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3371 try:
3372 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3373 except AttributeError:
3374 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00003375
Antoine Pitrou152efa22010-05-16 18:19:27 +00003376 for filename in [
Martin Panter3d81d932016-01-14 09:36:00 +00003377 CERTFILE, REMOTE_ROOT_CERT, BYTES_CERTFILE,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003378 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003379 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003380 BADCERT, BADKEY, EMPTYCERT]:
3381 if not os.path.exists(filename):
3382 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003383
Antoine Pitroub1fdf472014-10-05 20:41:53 +02003384 tests = [ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00003385
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003386 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00003387 tests.append(NetworkedTests)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02003388 tests.append(NetworkedBIOTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003389
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003390 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003391 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01003392 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00003393 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003394
Antoine Pitrou480a1242010-04-28 21:37:09 +00003395 try:
3396 support.run_unittest(*tests)
3397 finally:
3398 if _have_threads:
3399 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00003400
3401if __name__ == "__main__":
3402 test_main()