blob: 104b7f377a52dbfb108c6d526d24286b515267b3 [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 Pitrou803e6d62010-10-13 10:36:15 +000014import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000015import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000016import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000017import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000018import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000019import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000020
Antoine Pitrou05d936d2010-10-13 11:38:36 +000021ssl = support.import_module("ssl")
22
Martin Panter3840b2a2016-03-27 01:53:46 +000023try:
24 import threading
25except ImportError:
26 _have_threads = False
27else:
28 _have_threads = True
29
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010030PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000031HOST = support.HOST
Christian Heimes598894f2016-09-05 23:19:05 +020032IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
33IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
34
Antoine Pitrou152efa22010-05-16 18:19:27 +000035
Christian Heimesefff7062013-11-21 03:35:02 +010036def data_file(*name):
37 return os.path.join(os.path.dirname(__file__), *name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000038
Antoine Pitrou81564092010-10-08 23:06:24 +000039# The custom key and certificate files used in test_ssl are generated
40# using Lib/test/make_ssl_certs.py.
41# Other certificates are simply fetched from the Internet servers they
42# are meant to authenticate.
43
Antoine Pitrou152efa22010-05-16 18:19:27 +000044CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000045BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000046ONLYCERT = data_file("ssl_cert.pem")
47ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000048BYTES_ONLYCERT = os.fsencode(ONLYCERT)
49BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +020050CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
51ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
52KEY_PASSWORD = "somepass"
Antoine Pitrou152efa22010-05-16 18:19:27 +000053CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000054BYTES_CAPATH = os.fsencode(CAPATH)
Christian Heimesefff7062013-11-21 03:35:02 +010055CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
56CAFILE_CACERT = data_file("capath", "5ed36f99.0")
57
Antoine Pitrou152efa22010-05-16 18:19:27 +000058
Christian Heimes22587792013-11-21 23:56:13 +010059# empty CRL
60CRLFILE = data_file("revocation.crl")
61
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010062# Two keys and certs signed by the same CA (for SNI tests)
63SIGNED_CERTFILE = data_file("keycert3.pem")
64SIGNED_CERTFILE2 = data_file("keycert4.pem")
Martin Panter3840b2a2016-03-27 01:53:46 +000065# Same certificate as pycacert.pem, but without extra text in file
66SIGNING_CA = data_file("capath", "ceff1710.0")
Christian Heimes1c03abd2016-09-06 23:25:35 +020067# cert with all kinds of subject alt names
68ALLSANFILE = data_file("allsans.pem")
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010069
Martin Panter3d81d932016-01-14 09:36:00 +000070REMOTE_HOST = "self-signed.pythontest.net"
Antoine Pitrou152efa22010-05-16 18:19:27 +000071
72EMPTYCERT = data_file("nullcert.pem")
73BADCERT = data_file("badcert.pem")
Martin Panter407b62f2016-01-30 03:41:43 +000074NONEXISTINGCERT = data_file("XXXnonexisting.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000075BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020076NOKIACERT = data_file("nokia.pem")
Christian Heimes824f7f32013-08-17 00:54:47 +020077NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000078
Benjamin Petersona7eaf562015-04-02 00:04:06 -040079DHFILE = data_file("dh1024.pem")
Antoine Pitrou0e576f12011-12-22 10:03:38 +010080BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000081
Christian Heimes358cfd42016-09-10 22:43:48 +020082# Not defined in all versions of OpenSSL
83OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0)
84OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
85OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
86OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
87
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010088
Thomas Woutersed03b412007-08-28 21:37:11 +000089def handle_error(prefix):
90 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000091 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000092 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000093
Antoine Pitroub5218772010-05-21 09:56:06 +000094def can_clear_options():
95 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020096 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000097
98def no_sslv2_implies_sslv3_hello():
99 # 0.9.7h or higher
100 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
101
Christian Heimes2427b502013-11-23 11:24:32 +0100102def have_verify_flags():
103 # 0.9.8 or higher
104 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
105
Antoine Pitrouc695c952014-04-28 20:57:36 +0200106def utc_offset(): #NOTE: ignore issues like #1647654
107 # local time = utc time + utc offset
108 if time.daylight and time.localtime().tm_isdst > 0:
109 return -time.altzone # seconds
110 return -time.timezone
111
Christian Heimes9424bb42013-06-17 15:32:57 +0200112def asn1time(cert_time):
113 # Some versions of OpenSSL ignore seconds, see #18207
114 # 0.9.8.i
115 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
116 fmt = "%b %d %H:%M:%S %Y GMT"
117 dt = datetime.datetime.strptime(cert_time, fmt)
118 dt = dt.replace(second=0)
119 cert_time = dt.strftime(fmt)
120 # %d adds leading zero but ASN1_TIME_print() uses leading space
121 if cert_time[4] == "0":
122 cert_time = cert_time[:4] + " " + cert_time[5:]
123
124 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +0000125
Antoine Pitrou23df4832010-08-04 17:14:06 +0000126# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
127def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +0200128 if hasattr(ssl, 'PROTOCOL_SSLv2'):
129 @functools.wraps(func)
130 def f(*args, **kwargs):
131 try:
132 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
133 except ssl.SSLError:
134 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
135 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
136 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
137 return func(*args, **kwargs)
138 return f
139 else:
140 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000141
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100142needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
143
Antoine Pitrou23df4832010-08-04 17:14:06 +0000144
Christian Heimesd0486372016-09-10 23:23:33 +0200145def test_wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLS, *,
146 cert_reqs=ssl.CERT_NONE, ca_certs=None,
147 ciphers=None, certfile=None, keyfile=None,
148 **kwargs):
149 context = ssl.SSLContext(ssl_version)
150 if cert_reqs is not None:
151 context.verify_mode = cert_reqs
152 if ca_certs is not None:
153 context.load_verify_locations(ca_certs)
154 if certfile is not None or keyfile is not None:
155 context.load_cert_chain(certfile, keyfile)
156 if ciphers is not None:
157 context.set_ciphers(ciphers)
158 return context.wrap_socket(sock, **kwargs)
159
Antoine Pitrou152efa22010-05-16 18:19:27 +0000160class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000161
Antoine Pitrou480a1242010-04-28 21:37:09 +0000162 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000163 ssl.CERT_NONE
164 ssl.CERT_OPTIONAL
165 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100166 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100167 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100168 if ssl.HAS_ECDH:
169 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100170 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
171 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000172 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100173 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000174
Antoine Pitrou172f0252014-04-18 20:33:08 +0200175 def test_str_for_enums(self):
176 # Make sure that the PROTOCOL_* constants have enum-like string
177 # reprs.
Christian Heimes598894f2016-09-05 23:19:05 +0200178 proto = ssl.PROTOCOL_TLS
179 self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_TLS')
Antoine Pitrou172f0252014-04-18 20:33:08 +0200180 ctx = ssl.SSLContext(proto)
181 self.assertIs(ctx.protocol, proto)
182
Antoine Pitrou480a1242010-04-28 21:37:09 +0000183 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000184 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000185 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000186 sys.stdout.write("\n RAND_status is %d (%s)\n"
187 % (v, (v and "sufficient randomness") or
188 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200189
190 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
191 self.assertEqual(len(data), 16)
192 self.assertEqual(is_cryptographic, v == 1)
193 if v:
194 data = ssl.RAND_bytes(16)
195 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200196 else:
197 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200198
Victor Stinner1e81a392013-12-19 16:47:04 +0100199 # negative num is invalid
200 self.assertRaises(ValueError, ssl.RAND_bytes, -5)
201 self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5)
202
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100203 if hasattr(ssl, 'RAND_egd'):
204 self.assertRaises(TypeError, ssl.RAND_egd, 1)
205 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000206 ssl.RAND_add("this is a random string", 75.0)
Serhiy Storchaka8490f5a2015-03-20 09:00:36 +0200207 ssl.RAND_add(b"this is a random bytes object", 75.0)
208 ssl.RAND_add(bytearray(b"this is a random bytearray object"), 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000209
Christian Heimesf77b4b22013-08-21 13:26:05 +0200210 @unittest.skipUnless(os.name == 'posix', 'requires posix')
211 def test_random_fork(self):
212 status = ssl.RAND_status()
213 if not status:
214 self.fail("OpenSSL's PRNG has insufficient randomness")
215
216 rfd, wfd = os.pipe()
217 pid = os.fork()
218 if pid == 0:
219 try:
220 os.close(rfd)
221 child_random = ssl.RAND_pseudo_bytes(16)[0]
222 self.assertEqual(len(child_random), 16)
223 os.write(wfd, child_random)
224 os.close(wfd)
225 except BaseException:
226 os._exit(1)
227 else:
228 os._exit(0)
229 else:
230 os.close(wfd)
231 self.addCleanup(os.close, rfd)
232 _, status = os.waitpid(pid, 0)
233 self.assertEqual(status, 0)
234
235 child_random = os.read(rfd, 16)
236 self.assertEqual(len(child_random), 16)
237 parent_random = ssl.RAND_pseudo_bytes(16)[0]
238 self.assertEqual(len(parent_random), 16)
239
240 self.assertNotEqual(child_random, parent_random)
241
Antoine Pitrou480a1242010-04-28 21:37:09 +0000242 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000243 # note that this uses an 'unofficial' function in _ssl.c,
244 # provided solely for this test, to exercise the certificate
245 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000246 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000247 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000248 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200249 self.assertEqual(p['issuer'],
250 ((('countryName', 'XY'),),
251 (('localityName', 'Castle Anthrax'),),
252 (('organizationName', 'Python Software Foundation'),),
253 (('commonName', 'localhost'),))
254 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100255 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200256 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
257 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200258 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
259 self.assertEqual(p['subject'],
260 ((('countryName', 'XY'),),
261 (('localityName', 'Castle Anthrax'),),
262 (('organizationName', 'Python Software Foundation'),),
263 (('commonName', 'localhost'),))
264 )
265 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
266 # Issue #13034: the subjectAltName in some certificates
267 # (notably projects.developer.nokia.com:443) wasn't parsed
268 p = ssl._ssl._test_decode_cert(NOKIACERT)
269 if support.verbose:
270 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
271 self.assertEqual(p['subjectAltName'],
272 (('DNS', 'projects.developer.nokia.com'),
273 ('DNS', 'projects.forum.nokia.com'))
274 )
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100275 # extra OCSP and AIA fields
276 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
277 self.assertEqual(p['caIssuers'],
278 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
279 self.assertEqual(p['crlDistributionPoints'],
280 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Thomas Woutersed03b412007-08-28 21:37:11 +0000281
Christian Heimes824f7f32013-08-17 00:54:47 +0200282 def test_parse_cert_CVE_2013_4238(self):
283 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
284 if support.verbose:
285 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
286 subject = ((('countryName', 'US'),),
287 (('stateOrProvinceName', 'Oregon'),),
288 (('localityName', 'Beaverton'),),
289 (('organizationName', 'Python Software Foundation'),),
290 (('organizationalUnitName', 'Python Core Development'),),
291 (('commonName', 'null.python.org\x00example.org'),),
292 (('emailAddress', 'python-dev@python.org'),))
293 self.assertEqual(p['subject'], subject)
294 self.assertEqual(p['issuer'], subject)
Christian Heimes157c9832013-08-25 14:12:41 +0200295 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
296 san = (('DNS', 'altnull.python.org\x00example.com'),
297 ('email', 'null@python.org\x00user@example.org'),
298 ('URI', 'http://null.python.org\x00http://example.org'),
299 ('IP Address', '192.0.2.1'),
300 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
301 else:
302 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
303 san = (('DNS', 'altnull.python.org\x00example.com'),
304 ('email', 'null@python.org\x00user@example.org'),
305 ('URI', 'http://null.python.org\x00http://example.org'),
306 ('IP Address', '192.0.2.1'),
307 ('IP Address', '<invalid>'))
308
309 self.assertEqual(p['subjectAltName'], san)
Christian Heimes824f7f32013-08-17 00:54:47 +0200310
Christian Heimes1c03abd2016-09-06 23:25:35 +0200311 def test_parse_all_sans(self):
312 p = ssl._ssl._test_decode_cert(ALLSANFILE)
313 self.assertEqual(p['subjectAltName'],
314 (
315 ('DNS', 'allsans'),
316 ('othername', '<unsupported>'),
317 ('othername', '<unsupported>'),
318 ('email', 'user@example.org'),
319 ('DNS', 'www.example.org'),
320 ('DirName',
321 ((('countryName', 'XY'),),
322 (('localityName', 'Castle Anthrax'),),
323 (('organizationName', 'Python Software Foundation'),),
324 (('commonName', 'dirname example'),))),
325 ('URI', 'https://www.python.org/'),
326 ('IP Address', '127.0.0.1'),
327 ('IP Address', '0:0:0:0:0:0:0:1\n'),
328 ('Registered ID', '1.2.3.4.5')
329 )
330 )
331
Antoine Pitrou480a1242010-04-28 21:37:09 +0000332 def test_DER_to_PEM(self):
Martin Panter3d81d932016-01-14 09:36:00 +0000333 with open(CAFILE_CACERT, 'r') as f:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000334 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000335 d1 = ssl.PEM_cert_to_DER_cert(pem)
336 p2 = ssl.DER_cert_to_PEM_cert(d1)
337 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000338 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000339 if not p2.startswith(ssl.PEM_HEADER + '\n'):
340 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
341 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
342 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000343
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000344 def test_openssl_version(self):
345 n = ssl.OPENSSL_VERSION_NUMBER
346 t = ssl.OPENSSL_VERSION_INFO
347 s = ssl.OPENSSL_VERSION
348 self.assertIsInstance(n, int)
349 self.assertIsInstance(t, tuple)
350 self.assertIsInstance(s, str)
351 # Some sanity checks follow
352 # >= 0.9
353 self.assertGreaterEqual(n, 0x900000)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400354 # < 3.0
355 self.assertLess(n, 0x30000000)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000356 major, minor, fix, patch, status = t
357 self.assertGreaterEqual(major, 0)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400358 self.assertLess(major, 3)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000359 self.assertGreaterEqual(minor, 0)
360 self.assertLess(minor, 256)
361 self.assertGreaterEqual(fix, 0)
362 self.assertLess(fix, 256)
363 self.assertGreaterEqual(patch, 0)
Ned Deily05784a72015-02-05 17:20:13 +1100364 self.assertLessEqual(patch, 63)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000365 self.assertGreaterEqual(status, 0)
366 self.assertLessEqual(status, 15)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400367 # Version string as returned by {Open,Libre}SSL, the format might change
Christian Heimes598894f2016-09-05 23:19:05 +0200368 if IS_LIBRESSL:
369 self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
Victor Stinner789b8052015-01-06 11:51:06 +0100370 (s, t, hex(n)))
Antoine Pitroudfab9352014-07-21 18:35:01 -0400371 else:
372 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
Victor Stinner789b8052015-01-06 11:51:06 +0100373 (s, t, hex(n)))
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000374
Antoine Pitrou9d543662010-04-23 23:10:32 +0000375 @support.cpython_only
376 def test_refcycle(self):
377 # Issue #7943: an SSL object doesn't create reference cycles with
378 # itself.
379 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200380 ss = test_wrap_socket(s)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000381 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100382 with support.check_warnings(("", ResourceWarning)):
383 del ss
Victor Stinnere0b75b72016-03-21 17:26:04 +0100384 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000385
Antoine Pitroua468adc2010-09-14 14:43:44 +0000386 def test_wrapped_unconnected(self):
387 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200388 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000389 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200390 with test_wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100391 self.assertRaises(OSError, ss.recv, 1)
392 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
393 self.assertRaises(OSError, ss.recvfrom, 1)
394 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
395 self.assertRaises(OSError, ss.send, b'x')
396 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000397
Antoine Pitrou40f08742010-04-24 22:04:40 +0000398 def test_timeout(self):
399 # Issue #8524: when creating an SSL socket, the timeout of the
400 # original socket should be retained.
401 for timeout in (None, 0.0, 5.0):
402 s = socket.socket(socket.AF_INET)
403 s.settimeout(timeout)
Christian Heimesd0486372016-09-10 23:23:33 +0200404 with test_wrap_socket(s) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100405 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000406
Christian Heimesd0486372016-09-10 23:23:33 +0200407 def test_errors_sslwrap(self):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000408 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000409 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000410 "certfile must be specified",
411 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000412 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000413 "certfile must be specified for server-side operations",
414 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000415 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000416 "certfile must be specified for server-side operations",
Christian Heimesd0486372016-09-10 23:23:33 +0200417 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100418 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
419 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Christian Heimesd0486372016-09-10 23:23:33 +0200420 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200421 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000422 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000423 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000424 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200425 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000426 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000427 ssl.wrap_socket(sock,
428 certfile=CERTFILE, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000429 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200430 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000431 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000432 ssl.wrap_socket(sock,
433 certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000434 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000435
Martin Panter3464ea22016-02-01 21:58:11 +0000436 def bad_cert_test(self, certfile):
437 """Check that trying to use the given client certificate fails"""
438 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
439 certfile)
440 sock = socket.socket()
441 self.addCleanup(sock.close)
442 with self.assertRaises(ssl.SSLError):
Christian Heimesd0486372016-09-10 23:23:33 +0200443 test_wrap_socket(sock,
Martin Panter3464ea22016-02-01 21:58:11 +0000444 certfile=certfile,
445 ssl_version=ssl.PROTOCOL_TLSv1)
446
447 def test_empty_cert(self):
448 """Wrapping with an empty cert file"""
449 self.bad_cert_test("nullcert.pem")
450
451 def test_malformed_cert(self):
452 """Wrapping with a badly formatted certificate (syntax error)"""
453 self.bad_cert_test("badcert.pem")
454
455 def test_malformed_key(self):
456 """Wrapping with a badly formatted key (syntax error)"""
457 self.bad_cert_test("badkey.pem")
458
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000459 def test_match_hostname(self):
460 def ok(cert, hostname):
461 ssl.match_hostname(cert, hostname)
462 def fail(cert, hostname):
463 self.assertRaises(ssl.CertificateError,
464 ssl.match_hostname, cert, hostname)
465
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100466 # -- Hostname matching --
467
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000468 cert = {'subject': ((('commonName', 'example.com'),),)}
469 ok(cert, 'example.com')
470 ok(cert, 'ExAmple.cOm')
471 fail(cert, 'www.example.com')
472 fail(cert, '.example.com')
473 fail(cert, 'example.org')
474 fail(cert, 'exampleXcom')
475
476 cert = {'subject': ((('commonName', '*.a.com'),),)}
477 ok(cert, 'foo.a.com')
478 fail(cert, 'bar.foo.a.com')
479 fail(cert, 'a.com')
480 fail(cert, 'Xa.com')
481 fail(cert, '.a.com')
482
Georg Brandl72c98d32013-10-27 07:16:53 +0100483 # only match one left-most wildcard
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000484 cert = {'subject': ((('commonName', 'f*.com'),),)}
485 ok(cert, 'foo.com')
486 ok(cert, 'f.com')
487 fail(cert, 'bar.com')
488 fail(cert, 'foo.a.com')
489 fail(cert, 'bar.foo.com')
490
Christian Heimes824f7f32013-08-17 00:54:47 +0200491 # NULL bytes are bad, CVE-2013-4073
492 cert = {'subject': ((('commonName',
493 'null.python.org\x00example.org'),),)}
494 ok(cert, 'null.python.org\x00example.org') # or raise an error?
495 fail(cert, 'example.org')
496 fail(cert, 'null.python.org')
497
Georg Brandl72c98d32013-10-27 07:16:53 +0100498 # error cases with wildcards
499 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
500 fail(cert, 'bar.foo.a.com')
501 fail(cert, 'a.com')
502 fail(cert, 'Xa.com')
503 fail(cert, '.a.com')
504
505 cert = {'subject': ((('commonName', 'a.*.com'),),)}
506 fail(cert, 'a.foo.com')
507 fail(cert, 'a..com')
508 fail(cert, 'a.com')
509
510 # wildcard doesn't match IDNA prefix 'xn--'
511 idna = 'püthon.python.org'.encode("idna").decode("ascii")
512 cert = {'subject': ((('commonName', idna),),)}
513 ok(cert, idna)
514 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
515 fail(cert, idna)
516 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
517 fail(cert, idna)
518
519 # wildcard in first fragment and IDNA A-labels in sequent fragments
520 # are supported.
521 idna = 'www*.pythön.org'.encode("idna").decode("ascii")
522 cert = {'subject': ((('commonName', idna),),)}
523 ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
524 ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
525 fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
526 fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
527
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000528 # Slightly fake real-world example
529 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
530 'subject': ((('commonName', 'linuxfrz.org'),),),
531 'subjectAltName': (('DNS', 'linuxfr.org'),
532 ('DNS', 'linuxfr.com'),
533 ('othername', '<unsupported>'))}
534 ok(cert, 'linuxfr.org')
535 ok(cert, 'linuxfr.com')
536 # Not a "DNS" entry
537 fail(cert, '<unsupported>')
538 # When there is a subjectAltName, commonName isn't used
539 fail(cert, 'linuxfrz.org')
540
541 # A pristine real-world example
542 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
543 'subject': ((('countryName', 'US'),),
544 (('stateOrProvinceName', 'California'),),
545 (('localityName', 'Mountain View'),),
546 (('organizationName', 'Google Inc'),),
547 (('commonName', 'mail.google.com'),))}
548 ok(cert, 'mail.google.com')
549 fail(cert, 'gmail.com')
550 # Only commonName is considered
551 fail(cert, 'California')
552
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100553 # -- IPv4 matching --
554 cert = {'subject': ((('commonName', 'example.com'),),),
555 'subjectAltName': (('DNS', 'example.com'),
556 ('IP Address', '10.11.12.13'),
557 ('IP Address', '14.15.16.17'))}
558 ok(cert, '10.11.12.13')
559 ok(cert, '14.15.16.17')
560 fail(cert, '14.15.16.18')
561 fail(cert, 'example.net')
562
563 # -- IPv6 matching --
564 cert = {'subject': ((('commonName', 'example.com'),),),
565 'subjectAltName': (('DNS', 'example.com'),
566 ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'),
567 ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))}
568 ok(cert, '2001::cafe')
569 ok(cert, '2003::baba')
570 fail(cert, '2003::bebe')
571 fail(cert, 'example.net')
572
573 # -- Miscellaneous --
574
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000575 # Neither commonName nor subjectAltName
576 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
577 'subject': ((('countryName', 'US'),),
578 (('stateOrProvinceName', 'California'),),
579 (('localityName', 'Mountain View'),),
580 (('organizationName', 'Google Inc'),))}
581 fail(cert, 'mail.google.com')
582
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200583 # No DNS entry in subjectAltName but a commonName
584 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
585 'subject': ((('countryName', 'US'),),
586 (('stateOrProvinceName', 'California'),),
587 (('localityName', 'Mountain View'),),
588 (('commonName', 'mail.google.com'),)),
589 'subjectAltName': (('othername', 'blabla'), )}
590 ok(cert, 'mail.google.com')
591
592 # No DNS entry subjectAltName and no commonName
593 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
594 'subject': ((('countryName', 'US'),),
595 (('stateOrProvinceName', 'California'),),
596 (('localityName', 'Mountain View'),),
597 (('organizationName', 'Google Inc'),)),
598 'subjectAltName': (('othername', 'blabla'),)}
599 fail(cert, 'google.com')
600
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000601 # Empty cert / no cert
602 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
603 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
604
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200605 # Issue #17980: avoid denials of service by refusing more than one
606 # wildcard per fragment.
607 cert = {'subject': ((('commonName', 'a*b.com'),),)}
608 ok(cert, 'axxb.com')
609 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
Georg Brandl72c98d32013-10-27 07:16:53 +0100610 fail(cert, 'axxb.com')
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200611 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
612 with self.assertRaises(ssl.CertificateError) as cm:
613 ssl.match_hostname(cert, 'axxbxxc.com')
614 self.assertIn("too many wildcards", str(cm.exception))
615
Antoine Pitroud5323212010-10-22 18:19:07 +0000616 def test_server_side(self):
617 # server_hostname doesn't work for server sockets
618 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000619 with socket.socket() as sock:
620 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
621 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000622
Antoine Pitroud6494802011-07-21 01:11:30 +0200623 def test_unknown_channel_binding(self):
624 # should raise ValueError for unknown type
625 s = socket.socket(socket.AF_INET)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200626 s.bind(('127.0.0.1', 0))
627 s.listen()
628 c = socket.socket(socket.AF_INET)
629 c.connect(s.getsockname())
Christian Heimesd0486372016-09-10 23:23:33 +0200630 with test_wrap_socket(c, do_handshake_on_connect=False) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100631 with self.assertRaises(ValueError):
632 ss.get_channel_binding("unknown-type")
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200633 s.close()
Antoine Pitroud6494802011-07-21 01:11:30 +0200634
635 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
636 "'tls-unique' channel binding not available")
637 def test_tls_unique_channel_binding(self):
638 # unconnected should return None for known type
639 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200640 with test_wrap_socket(s) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100641 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200642 # the same for server-side
643 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200644 with test_wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100645 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200646
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600647 def test_dealloc_warn(self):
Christian Heimesd0486372016-09-10 23:23:33 +0200648 ss = test_wrap_socket(socket.socket(socket.AF_INET))
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600649 r = repr(ss)
650 with self.assertWarns(ResourceWarning) as cm:
651 ss = None
652 support.gc_collect()
653 self.assertIn(r, str(cm.warning.args[0]))
654
Christian Heimes6d7ad132013-06-09 18:02:55 +0200655 def test_get_default_verify_paths(self):
656 paths = ssl.get_default_verify_paths()
657 self.assertEqual(len(paths), 6)
658 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
659
660 with support.EnvironmentVarGuard() as env:
661 env["SSL_CERT_DIR"] = CAPATH
662 env["SSL_CERT_FILE"] = CERTFILE
663 paths = ssl.get_default_verify_paths()
664 self.assertEqual(paths.cafile, CERTFILE)
665 self.assertEqual(paths.capath, CAPATH)
666
Christian Heimes44109d72013-11-22 01:51:30 +0100667 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
668 def test_enum_certificates(self):
669 self.assertTrue(ssl.enum_certificates("CA"))
670 self.assertTrue(ssl.enum_certificates("ROOT"))
671
672 self.assertRaises(TypeError, ssl.enum_certificates)
673 self.assertRaises(WindowsError, ssl.enum_certificates, "")
674
Christian Heimesc2d65e12013-11-22 16:13:55 +0100675 trust_oids = set()
676 for storename in ("CA", "ROOT"):
677 store = ssl.enum_certificates(storename)
678 self.assertIsInstance(store, list)
679 for element in store:
680 self.assertIsInstance(element, tuple)
681 self.assertEqual(len(element), 3)
682 cert, enc, trust = element
683 self.assertIsInstance(cert, bytes)
684 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
685 self.assertIsInstance(trust, (set, bool))
686 if isinstance(trust, set):
687 trust_oids.update(trust)
Christian Heimes44109d72013-11-22 01:51:30 +0100688
689 serverAuth = "1.3.6.1.5.5.7.3.1"
Christian Heimesc2d65e12013-11-22 16:13:55 +0100690 self.assertIn(serverAuth, trust_oids)
Christian Heimes6d7ad132013-06-09 18:02:55 +0200691
Christian Heimes46bebee2013-06-09 19:03:31 +0200692 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Christian Heimes44109d72013-11-22 01:51:30 +0100693 def test_enum_crls(self):
694 self.assertTrue(ssl.enum_crls("CA"))
695 self.assertRaises(TypeError, ssl.enum_crls)
696 self.assertRaises(WindowsError, ssl.enum_crls, "")
Christian Heimes46bebee2013-06-09 19:03:31 +0200697
Christian Heimes44109d72013-11-22 01:51:30 +0100698 crls = ssl.enum_crls("CA")
699 self.assertIsInstance(crls, list)
700 for element in crls:
701 self.assertIsInstance(element, tuple)
702 self.assertEqual(len(element), 2)
703 self.assertIsInstance(element[0], bytes)
704 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
Christian Heimes46bebee2013-06-09 19:03:31 +0200705
Christian Heimes46bebee2013-06-09 19:03:31 +0200706
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100707 def test_asn1object(self):
708 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
709 '1.3.6.1.5.5.7.3.1')
710
711 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
712 self.assertEqual(val, expected)
713 self.assertEqual(val.nid, 129)
714 self.assertEqual(val.shortname, 'serverAuth')
715 self.assertEqual(val.longname, 'TLS Web Server Authentication')
716 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
717 self.assertIsInstance(val, ssl._ASN1Object)
718 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
719
720 val = ssl._ASN1Object.fromnid(129)
721 self.assertEqual(val, expected)
722 self.assertIsInstance(val, ssl._ASN1Object)
723 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100724 with self.assertRaisesRegex(ValueError, "unknown NID 100000"):
725 ssl._ASN1Object.fromnid(100000)
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100726 for i in range(1000):
727 try:
728 obj = ssl._ASN1Object.fromnid(i)
729 except ValueError:
730 pass
731 else:
732 self.assertIsInstance(obj.nid, int)
733 self.assertIsInstance(obj.shortname, str)
734 self.assertIsInstance(obj.longname, str)
735 self.assertIsInstance(obj.oid, (str, type(None)))
736
737 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
738 self.assertEqual(val, expected)
739 self.assertIsInstance(val, ssl._ASN1Object)
740 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
741 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
742 expected)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100743 with self.assertRaisesRegex(ValueError, "unknown object 'serverauth'"):
744 ssl._ASN1Object.fromname('serverauth')
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100745
Christian Heimes72d28502013-11-23 13:56:58 +0100746 def test_purpose_enum(self):
747 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
748 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
749 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
750 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
751 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
752 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
753 '1.3.6.1.5.5.7.3.1')
754
755 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
756 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
757 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
758 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
759 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
760 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
761 '1.3.6.1.5.5.7.3.2')
762
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100763 def test_unsupported_dtls(self):
764 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
765 self.addCleanup(s.close)
766 with self.assertRaises(NotImplementedError) as cx:
Christian Heimesd0486372016-09-10 23:23:33 +0200767 test_wrap_socket(s, cert_reqs=ssl.CERT_NONE)
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100768 self.assertEqual(str(cx.exception), "only stream sockets are supported")
769 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
770 with self.assertRaises(NotImplementedError) as cx:
771 ctx.wrap_socket(s)
772 self.assertEqual(str(cx.exception), "only stream sockets are supported")
773
Antoine Pitrouc695c952014-04-28 20:57:36 +0200774 def cert_time_ok(self, timestring, timestamp):
775 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
776
777 def cert_time_fail(self, timestring):
778 with self.assertRaises(ValueError):
779 ssl.cert_time_to_seconds(timestring)
780
781 @unittest.skipUnless(utc_offset(),
782 'local time needs to be different from UTC')
783 def test_cert_time_to_seconds_timezone(self):
784 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
785 # results if local timezone is not UTC
786 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
787 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
788
789 def test_cert_time_to_seconds(self):
790 timestring = "Jan 5 09:34:43 2018 GMT"
791 ts = 1515144883.0
792 self.cert_time_ok(timestring, ts)
793 # accept keyword parameter, assert its name
794 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
795 # accept both %e and %d (space or zero generated by strftime)
796 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
797 # case-insensitive
798 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
799 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
800 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
801 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
802 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
803 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
804 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
805 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
806
807 newyear_ts = 1230768000.0
808 # leap seconds
809 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
810 # same timestamp
811 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
812
813 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
814 # allow 60th second (even if it is not a leap second)
815 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
816 # allow 2nd leap second for compatibility with time.strptime()
817 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
818 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
819
820 # no special treatement for the special value:
821 # 99991231235959Z (rfc 5280)
822 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
823
824 @support.run_with_locale('LC_ALL', '')
825 def test_cert_time_to_seconds_locale(self):
826 # `cert_time_to_seconds()` should be locale independent
827
828 def local_february_name():
829 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
830
831 if local_february_name().lower() == 'feb':
832 self.skipTest("locale-specific month name needs to be "
833 "different from C locale")
834
835 # locale-independent
836 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
837 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
838
Martin Panter3840b2a2016-03-27 01:53:46 +0000839 def test_connect_ex_error(self):
840 server = socket.socket(socket.AF_INET)
841 self.addCleanup(server.close)
842 port = support.bind_port(server) # Reserve port but don't listen
Christian Heimesd0486372016-09-10 23:23:33 +0200843 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +0000844 cert_reqs=ssl.CERT_REQUIRED)
845 self.addCleanup(s.close)
846 rc = s.connect_ex((HOST, port))
847 # Issue #19919: Windows machines or VMs hosted on Windows
848 # machines sometimes return EWOULDBLOCK.
849 errors = (
850 errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
851 errno.EWOULDBLOCK,
852 )
853 self.assertIn(rc, errors)
854
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100855
Antoine Pitrou152efa22010-05-16 18:19:27 +0000856class ContextTests(unittest.TestCase):
857
Antoine Pitrou23df4832010-08-04 17:14:06 +0000858 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000859 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100860 for protocol in PROTOCOLS:
861 ssl.SSLContext(protocol)
Christian Heimes598894f2016-09-05 23:19:05 +0200862 ctx = ssl.SSLContext()
863 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000864 self.assertRaises(ValueError, ssl.SSLContext, -1)
865 self.assertRaises(ValueError, ssl.SSLContext, 42)
866
Antoine Pitrou23df4832010-08-04 17:14:06 +0000867 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000868 def test_protocol(self):
869 for proto in PROTOCOLS:
870 ctx = ssl.SSLContext(proto)
871 self.assertEqual(ctx.protocol, proto)
872
873 def test_ciphers(self):
874 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
875 ctx.set_ciphers("ALL")
876 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000877 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000878 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000879
Christian Heimes25bfcd52016-09-06 00:04:45 +0200880 @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old')
881 def test_get_ciphers(self):
882 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Christian Heimesea9b2dc2016-09-06 10:45:44 +0200883 ctx.set_ciphers('AESGCM')
Christian Heimes25bfcd52016-09-06 00:04:45 +0200884 names = set(d['name'] for d in ctx.get_ciphers())
Christian Heimes582282b2016-09-06 11:27:25 +0200885 self.assertIn('AES256-GCM-SHA384', names)
886 self.assertIn('AES128-GCM-SHA256', names)
Christian Heimes25bfcd52016-09-06 00:04:45 +0200887
Antoine Pitrou23df4832010-08-04 17:14:06 +0000888 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000889 def test_options(self):
890 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800891 # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
Christian Heimes598894f2016-09-05 23:19:05 +0200892 default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
Christian Heimes358cfd42016-09-10 22:43:48 +0200893 # SSLContext also enables these by default
894 default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE |
895 OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE)
Christian Heimes598894f2016-09-05 23:19:05 +0200896 self.assertEqual(default, ctx.options)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800897 ctx.options |= ssl.OP_NO_TLSv1
Christian Heimes598894f2016-09-05 23:19:05 +0200898 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000899 if can_clear_options():
Christian Heimes598894f2016-09-05 23:19:05 +0200900 ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
901 self.assertEqual(default, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000902 ctx.options = 0
Matthias Klosef7c56242016-06-12 23:40:00 -0700903 # Ubuntu has OP_NO_SSLv3 forced on by default
904 self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
Antoine Pitroub5218772010-05-21 09:56:06 +0000905 else:
906 with self.assertRaises(ValueError):
907 ctx.options = 0
908
Christian Heimes22587792013-11-21 23:56:13 +0100909 def test_verify_mode(self):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000910 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
911 # Default value
912 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
913 ctx.verify_mode = ssl.CERT_OPTIONAL
914 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
915 ctx.verify_mode = ssl.CERT_REQUIRED
916 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
917 ctx.verify_mode = ssl.CERT_NONE
918 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
919 with self.assertRaises(TypeError):
920 ctx.verify_mode = None
921 with self.assertRaises(ValueError):
922 ctx.verify_mode = 42
923
Christian Heimes2427b502013-11-23 11:24:32 +0100924 @unittest.skipUnless(have_verify_flags(),
925 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +0100926 def test_verify_flags(self):
927 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson990fcaa2015-03-04 22:49:41 -0500928 # default value
929 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
930 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +0100931 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
932 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
933 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
934 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
935 ctx.verify_flags = ssl.VERIFY_DEFAULT
936 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
937 # supports any value
938 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
939 self.assertEqual(ctx.verify_flags,
940 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
941 with self.assertRaises(TypeError):
942 ctx.verify_flags = None
943
Antoine Pitrou152efa22010-05-16 18:19:27 +0000944 def test_load_cert_chain(self):
945 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
946 # Combined key and cert in a single file
Benjamin Peterson1ea070e2014-11-03 21:05:01 -0500947 ctx.load_cert_chain(CERTFILE, keyfile=None)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000948 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
949 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200950 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000951 ctx.load_cert_chain(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000952 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000953 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000954 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000955 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000956 ctx.load_cert_chain(EMPTYCERT)
957 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000958 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000959 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
960 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
961 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000962 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000963 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000964 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000965 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000966 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000967 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
968 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000969 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000970 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Martin Panter3d81d932016-01-14 09:36:00 +0000971 ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200972 # Password protected key and cert
973 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
974 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
975 ctx.load_cert_chain(CERTFILE_PROTECTED,
976 password=bytearray(KEY_PASSWORD.encode()))
977 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
978 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
979 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
980 bytearray(KEY_PASSWORD.encode()))
981 with self.assertRaisesRegex(TypeError, "should be a string"):
982 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
983 with self.assertRaises(ssl.SSLError):
984 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
985 with self.assertRaisesRegex(ValueError, "cannot be longer"):
986 # openssl has a fixed limit on the password buffer.
987 # PEM_BUFSIZE is generally set to 1kb.
988 # Return a string larger than this.
989 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
990 # Password callback
991 def getpass_unicode():
992 return KEY_PASSWORD
993 def getpass_bytes():
994 return KEY_PASSWORD.encode()
995 def getpass_bytearray():
996 return bytearray(KEY_PASSWORD.encode())
997 def getpass_badpass():
998 return "badpass"
999 def getpass_huge():
1000 return b'a' * (1024 * 1024)
1001 def getpass_bad_type():
1002 return 9
1003 def getpass_exception():
1004 raise Exception('getpass error')
1005 class GetPassCallable:
1006 def __call__(self):
1007 return KEY_PASSWORD
1008 def getpass(self):
1009 return KEY_PASSWORD
1010 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
1011 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
1012 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
1013 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
1014 ctx.load_cert_chain(CERTFILE_PROTECTED,
1015 password=GetPassCallable().getpass)
1016 with self.assertRaises(ssl.SSLError):
1017 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
1018 with self.assertRaisesRegex(ValueError, "cannot be longer"):
1019 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
1020 with self.assertRaisesRegex(TypeError, "must return a string"):
1021 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
1022 with self.assertRaisesRegex(Exception, "getpass error"):
1023 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
1024 # Make sure the password function isn't called if it isn't needed
1025 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001026
1027 def test_load_verify_locations(self):
1028 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1029 ctx.load_verify_locations(CERTFILE)
1030 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
1031 ctx.load_verify_locations(BYTES_CERTFILE)
1032 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
1033 self.assertRaises(TypeError, ctx.load_verify_locations)
Christian Heimesefff7062013-11-21 03:35:02 +01001034 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001035 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001036 ctx.load_verify_locations(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +00001037 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001038 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +00001039 ctx.load_verify_locations(BADCERT)
1040 ctx.load_verify_locations(CERTFILE, CAPATH)
1041 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
1042
Victor Stinner80f75e62011-01-29 11:31:20 +00001043 # Issue #10989: crash if the second argument type is invalid
1044 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
1045
Christian Heimesefff7062013-11-21 03:35:02 +01001046 def test_load_verify_cadata(self):
1047 # test cadata
1048 with open(CAFILE_CACERT) as f:
1049 cacert_pem = f.read()
1050 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
1051 with open(CAFILE_NEURONIO) as f:
1052 neuronio_pem = f.read()
1053 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
1054
1055 # test PEM
1056 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1057 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
1058 ctx.load_verify_locations(cadata=cacert_pem)
1059 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
1060 ctx.load_verify_locations(cadata=neuronio_pem)
1061 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1062 # cert already in hash table
1063 ctx.load_verify_locations(cadata=neuronio_pem)
1064 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1065
1066 # combined
1067 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1068 combined = "\n".join((cacert_pem, neuronio_pem))
1069 ctx.load_verify_locations(cadata=combined)
1070 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1071
1072 # with junk around the certs
1073 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1074 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
1075 neuronio_pem, "tail"]
1076 ctx.load_verify_locations(cadata="\n".join(combined))
1077 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1078
1079 # test DER
1080 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1081 ctx.load_verify_locations(cadata=cacert_der)
1082 ctx.load_verify_locations(cadata=neuronio_der)
1083 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1084 # cert already in hash table
1085 ctx.load_verify_locations(cadata=cacert_der)
1086 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1087
1088 # combined
1089 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1090 combined = b"".join((cacert_der, neuronio_der))
1091 ctx.load_verify_locations(cadata=combined)
1092 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1093
1094 # error cases
1095 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1096 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
1097
1098 with self.assertRaisesRegex(ssl.SSLError, "no start line"):
1099 ctx.load_verify_locations(cadata="broken")
1100 with self.assertRaisesRegex(ssl.SSLError, "not enough data"):
1101 ctx.load_verify_locations(cadata=b"broken")
1102
1103
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001104 def test_load_dh_params(self):
1105 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1106 ctx.load_dh_params(DHFILE)
1107 if os.name != 'nt':
1108 ctx.load_dh_params(BYTES_DHFILE)
1109 self.assertRaises(TypeError, ctx.load_dh_params)
1110 self.assertRaises(TypeError, ctx.load_dh_params, None)
1111 with self.assertRaises(FileNotFoundError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001112 ctx.load_dh_params(NONEXISTINGCERT)
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001113 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001114 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001115 ctx.load_dh_params(CERTFILE)
1116
Antoine Pitroueb585ad2010-10-22 18:24:20 +00001117 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +00001118 def test_session_stats(self):
1119 for proto in PROTOCOLS:
1120 ctx = ssl.SSLContext(proto)
1121 self.assertEqual(ctx.session_stats(), {
1122 'number': 0,
1123 'connect': 0,
1124 'connect_good': 0,
1125 'connect_renegotiate': 0,
1126 'accept': 0,
1127 'accept_good': 0,
1128 'accept_renegotiate': 0,
1129 'hits': 0,
1130 'misses': 0,
1131 'timeouts': 0,
1132 'cache_full': 0,
1133 })
1134
Antoine Pitrou664c2d12010-11-17 20:29:42 +00001135 def test_set_default_verify_paths(self):
1136 # There's not much we can do to test that it acts as expected,
1137 # so just check it doesn't crash or raise an exception.
1138 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1139 ctx.set_default_verify_paths()
1140
Antoine Pitrou501da612011-12-21 09:27:41 +01001141 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +01001142 def test_set_ecdh_curve(self):
1143 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1144 ctx.set_ecdh_curve("prime256v1")
1145 ctx.set_ecdh_curve(b"prime256v1")
1146 self.assertRaises(TypeError, ctx.set_ecdh_curve)
1147 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
1148 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
1149 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
1150
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001151 @needs_sni
1152 def test_sni_callback(self):
1153 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1154
1155 # set_servername_callback expects a callable, or None
1156 self.assertRaises(TypeError, ctx.set_servername_callback)
1157 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
1158 self.assertRaises(TypeError, ctx.set_servername_callback, "")
1159 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
1160
1161 def dummycallback(sock, servername, ctx):
1162 pass
1163 ctx.set_servername_callback(None)
1164 ctx.set_servername_callback(dummycallback)
1165
1166 @needs_sni
1167 def test_sni_callback_refcycle(self):
1168 # Reference cycles through the servername callback are detected
1169 # and cleared.
1170 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1171 def dummycallback(sock, servername, ctx, cycle=ctx):
1172 pass
1173 ctx.set_servername_callback(dummycallback)
1174 wr = weakref.ref(ctx)
1175 del ctx, dummycallback
1176 gc.collect()
1177 self.assertIs(wr(), None)
1178
Christian Heimes9a5395a2013-06-17 15:44:12 +02001179 def test_cert_store_stats(self):
1180 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1181 self.assertEqual(ctx.cert_store_stats(),
1182 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1183 ctx.load_cert_chain(CERTFILE)
1184 self.assertEqual(ctx.cert_store_stats(),
1185 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1186 ctx.load_verify_locations(CERTFILE)
1187 self.assertEqual(ctx.cert_store_stats(),
1188 {'x509_ca': 0, 'crl': 0, 'x509': 1})
Martin Panterb55f8b72016-01-14 12:53:56 +00001189 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001190 self.assertEqual(ctx.cert_store_stats(),
1191 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1192
1193 def test_get_ca_certs(self):
1194 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1195 self.assertEqual(ctx.get_ca_certs(), [])
1196 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1197 ctx.load_verify_locations(CERTFILE)
1198 self.assertEqual(ctx.get_ca_certs(), [])
Martin Panterb55f8b72016-01-14 12:53:56 +00001199 # but CAFILE_CACERT is a CA cert
1200 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001201 self.assertEqual(ctx.get_ca_certs(),
1202 [{'issuer': ((('organizationName', 'Root CA'),),
1203 (('organizationalUnitName', 'http://www.cacert.org'),),
1204 (('commonName', 'CA Cert Signing Authority'),),
1205 (('emailAddress', 'support@cacert.org'),)),
1206 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1207 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1208 'serialNumber': '00',
Christian Heimesbd3a7f92013-11-21 03:40:15 +01001209 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
Christian Heimes9a5395a2013-06-17 15:44:12 +02001210 'subject': ((('organizationName', 'Root CA'),),
1211 (('organizationalUnitName', 'http://www.cacert.org'),),
1212 (('commonName', 'CA Cert Signing Authority'),),
1213 (('emailAddress', 'support@cacert.org'),)),
1214 'version': 3}])
1215
Martin Panterb55f8b72016-01-14 12:53:56 +00001216 with open(CAFILE_CACERT) as f:
Christian Heimes9a5395a2013-06-17 15:44:12 +02001217 pem = f.read()
1218 der = ssl.PEM_cert_to_DER_cert(pem)
1219 self.assertEqual(ctx.get_ca_certs(True), [der])
1220
Christian Heimes72d28502013-11-23 13:56:58 +01001221 def test_load_default_certs(self):
1222 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1223 ctx.load_default_certs()
1224
1225 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1226 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1227 ctx.load_default_certs()
1228
1229 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1230 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1231
1232 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1233 self.assertRaises(TypeError, ctx.load_default_certs, None)
1234 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1235
Benjamin Peterson91244e02014-10-03 18:17:15 -04001236 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Christian Heimes598894f2016-09-05 23:19:05 +02001237 @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
Benjamin Peterson5915b0f2014-10-03 17:27:05 -04001238 def test_load_default_certs_env(self):
1239 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1240 with support.EnvironmentVarGuard() as env:
1241 env["SSL_CERT_DIR"] = CAPATH
1242 env["SSL_CERT_FILE"] = CERTFILE
1243 ctx.load_default_certs()
1244 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1245
Benjamin Peterson91244e02014-10-03 18:17:15 -04001246 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Steve Dower68d663c2017-07-17 11:15:48 +02001247 @unittest.skipIf(hasattr(sys, "gettotalrefcount"), "Debug build does not share environment between CRTs")
Benjamin Peterson91244e02014-10-03 18:17:15 -04001248 def test_load_default_certs_env_windows(self):
1249 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1250 ctx.load_default_certs()
1251 stats = ctx.cert_store_stats()
1252
1253 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1254 with support.EnvironmentVarGuard() as env:
1255 env["SSL_CERT_DIR"] = CAPATH
1256 env["SSL_CERT_FILE"] = CERTFILE
1257 ctx.load_default_certs()
1258 stats["x509"] += 1
1259 self.assertEqual(ctx.cert_store_stats(), stats)
1260
Christian Heimes358cfd42016-09-10 22:43:48 +02001261 def _assert_context_options(self, ctx):
1262 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1263 if OP_NO_COMPRESSION != 0:
1264 self.assertEqual(ctx.options & OP_NO_COMPRESSION,
1265 OP_NO_COMPRESSION)
1266 if OP_SINGLE_DH_USE != 0:
1267 self.assertEqual(ctx.options & OP_SINGLE_DH_USE,
1268 OP_SINGLE_DH_USE)
1269 if OP_SINGLE_ECDH_USE != 0:
1270 self.assertEqual(ctx.options & OP_SINGLE_ECDH_USE,
1271 OP_SINGLE_ECDH_USE)
1272 if OP_CIPHER_SERVER_PREFERENCE != 0:
1273 self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE,
1274 OP_CIPHER_SERVER_PREFERENCE)
1275
Christian Heimes4c05b472013-11-23 15:58:30 +01001276 def test_create_default_context(self):
1277 ctx = ssl.create_default_context()
Christian Heimes358cfd42016-09-10 22:43:48 +02001278
Donald Stufft6a2ba942014-03-23 19:05:28 -04001279 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001280 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001281 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001282 self._assert_context_options(ctx)
1283
Christian Heimes4c05b472013-11-23 15:58:30 +01001284
1285 with open(SIGNING_CA) as f:
1286 cadata = f.read()
1287 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1288 cadata=cadata)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001289 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001290 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes358cfd42016-09-10 22:43:48 +02001291 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001292
1293 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001294 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001295 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001296 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001297
Christian Heimes67986f92013-11-23 22:43:47 +01001298 def test__create_stdlib_context(self):
1299 ctx = ssl._create_stdlib_context()
1300 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1301 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001302 self.assertFalse(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001303 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001304
1305 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1306 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1307 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001308 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001309
1310 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001311 cert_reqs=ssl.CERT_REQUIRED,
1312 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001313 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1314 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001315 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001316 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001317
1318 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1319 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1320 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001321 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001322
Christian Heimes1aa9a752013-12-02 02:41:19 +01001323 def test_check_hostname(self):
1324 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1325 self.assertFalse(ctx.check_hostname)
1326
1327 # Requires CERT_REQUIRED or CERT_OPTIONAL
1328 with self.assertRaises(ValueError):
1329 ctx.check_hostname = True
1330 ctx.verify_mode = ssl.CERT_REQUIRED
1331 self.assertFalse(ctx.check_hostname)
1332 ctx.check_hostname = True
1333 self.assertTrue(ctx.check_hostname)
1334
1335 ctx.verify_mode = ssl.CERT_OPTIONAL
1336 ctx.check_hostname = True
1337 self.assertTrue(ctx.check_hostname)
1338
1339 # Cannot set CERT_NONE with check_hostname enabled
1340 with self.assertRaises(ValueError):
1341 ctx.verify_mode = ssl.CERT_NONE
1342 ctx.check_hostname = False
1343 self.assertFalse(ctx.check_hostname)
1344
Christian Heimes5fe668c2016-09-12 00:01:11 +02001345 def test_context_client_server(self):
1346 # PROTOCOL_TLS_CLIENT has sane defaults
1347 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
1348 self.assertTrue(ctx.check_hostname)
1349 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1350
1351 # PROTOCOL_TLS_SERVER has different but also sane defaults
1352 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
1353 self.assertFalse(ctx.check_hostname)
1354 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1355
Antoine Pitrou152efa22010-05-16 18:19:27 +00001356
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001357class SSLErrorTests(unittest.TestCase):
1358
1359 def test_str(self):
1360 # The str() of a SSLError doesn't include the errno
1361 e = ssl.SSLError(1, "foo")
1362 self.assertEqual(str(e), "foo")
1363 self.assertEqual(e.errno, 1)
1364 # Same for a subclass
1365 e = ssl.SSLZeroReturnError(1, "foo")
1366 self.assertEqual(str(e), "foo")
1367 self.assertEqual(e.errno, 1)
1368
1369 def test_lib_reason(self):
1370 # Test the library and reason attributes
1371 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1372 with self.assertRaises(ssl.SSLError) as cm:
1373 ctx.load_dh_params(CERTFILE)
1374 self.assertEqual(cm.exception.library, 'PEM')
1375 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1376 s = str(cm.exception)
1377 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1378
1379 def test_subclass(self):
1380 # Check that the appropriate SSLError subclass is raised
1381 # (this only tests one of them)
1382 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1383 with socket.socket() as s:
1384 s.bind(("127.0.0.1", 0))
Charles-François Natali6e204602014-07-23 19:28:13 +01001385 s.listen()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001386 c = socket.socket()
1387 c.connect(s.getsockname())
1388 c.setblocking(False)
1389 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001390 with self.assertRaises(ssl.SSLWantReadError) as cm:
1391 c.do_handshake()
1392 s = str(cm.exception)
1393 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1394 # For compatibility
1395 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1396
Nathaniel J. Smith59fdf0f2017-06-09 02:35:16 -07001397 def test_bad_idna_in_server_hostname(self):
1398 # Note: this test is testing some code that probably shouldn't exist
1399 # in the first place, so if it starts failing at some point because
1400 # you made the ssl module stop doing IDNA decoding then please feel
1401 # free to remove it. The test was mainly added because this case used
1402 # to cause memory corruption (see bpo-30594).
1403 ctx = ssl.create_default_context()
1404 with self.assertRaises(UnicodeError):
1405 ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO(),
1406 server_hostname="xn--.com")
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001407
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001408class MemoryBIOTests(unittest.TestCase):
1409
1410 def test_read_write(self):
1411 bio = ssl.MemoryBIO()
1412 bio.write(b'foo')
1413 self.assertEqual(bio.read(), b'foo')
1414 self.assertEqual(bio.read(), b'')
1415 bio.write(b'foo')
1416 bio.write(b'bar')
1417 self.assertEqual(bio.read(), b'foobar')
1418 self.assertEqual(bio.read(), b'')
1419 bio.write(b'baz')
1420 self.assertEqual(bio.read(2), b'ba')
1421 self.assertEqual(bio.read(1), b'z')
1422 self.assertEqual(bio.read(1), b'')
1423
1424 def test_eof(self):
1425 bio = ssl.MemoryBIO()
1426 self.assertFalse(bio.eof)
1427 self.assertEqual(bio.read(), b'')
1428 self.assertFalse(bio.eof)
1429 bio.write(b'foo')
1430 self.assertFalse(bio.eof)
1431 bio.write_eof()
1432 self.assertFalse(bio.eof)
1433 self.assertEqual(bio.read(2), b'fo')
1434 self.assertFalse(bio.eof)
1435 self.assertEqual(bio.read(1), b'o')
1436 self.assertTrue(bio.eof)
1437 self.assertEqual(bio.read(), b'')
1438 self.assertTrue(bio.eof)
1439
1440 def test_pending(self):
1441 bio = ssl.MemoryBIO()
1442 self.assertEqual(bio.pending, 0)
1443 bio.write(b'foo')
1444 self.assertEqual(bio.pending, 3)
1445 for i in range(3):
1446 bio.read(1)
1447 self.assertEqual(bio.pending, 3-i-1)
1448 for i in range(3):
1449 bio.write(b'x')
1450 self.assertEqual(bio.pending, i+1)
1451 bio.read()
1452 self.assertEqual(bio.pending, 0)
1453
1454 def test_buffer_types(self):
1455 bio = ssl.MemoryBIO()
1456 bio.write(b'foo')
1457 self.assertEqual(bio.read(), b'foo')
1458 bio.write(bytearray(b'bar'))
1459 self.assertEqual(bio.read(), b'bar')
1460 bio.write(memoryview(b'baz'))
1461 self.assertEqual(bio.read(), b'baz')
1462
1463 def test_error_types(self):
1464 bio = ssl.MemoryBIO()
1465 self.assertRaises(TypeError, bio.write, 'foo')
1466 self.assertRaises(TypeError, bio.write, None)
1467 self.assertRaises(TypeError, bio.write, True)
1468 self.assertRaises(TypeError, bio.write, 1)
1469
1470
Martin Panter3840b2a2016-03-27 01:53:46 +00001471@unittest.skipUnless(_have_threads, "Needs threading module")
1472class SimpleBackgroundTests(unittest.TestCase):
1473
1474 """Tests that connect to a simple server running in the background"""
1475
1476 def setUp(self):
1477 server = ThreadedEchoServer(SIGNED_CERTFILE)
1478 self.server_addr = (HOST, server.port)
1479 server.__enter__()
1480 self.addCleanup(server.__exit__, None, None, None)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001481
Antoine Pitrou480a1242010-04-28 21:37:09 +00001482 def test_connect(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001483 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001484 cert_reqs=ssl.CERT_NONE) as s:
1485 s.connect(self.server_addr)
1486 self.assertEqual({}, s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001487 self.assertFalse(s.server_side)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001488
Martin Panter3840b2a2016-03-27 01:53:46 +00001489 # this should succeed because we specify the root cert
Christian Heimesd0486372016-09-10 23:23:33 +02001490 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001491 cert_reqs=ssl.CERT_REQUIRED,
1492 ca_certs=SIGNING_CA) as s:
1493 s.connect(self.server_addr)
1494 self.assertTrue(s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001495 self.assertFalse(s.server_side)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001496
Martin Panter3840b2a2016-03-27 01:53:46 +00001497 def test_connect_fail(self):
1498 # This should fail because we have no verification certs. Connection
1499 # failure crashes ThreadedEchoServer, so run this in an independent
1500 # test method.
Christian Heimesd0486372016-09-10 23:23:33 +02001501 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001502 cert_reqs=ssl.CERT_REQUIRED)
1503 self.addCleanup(s.close)
1504 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1505 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001506
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001507 def test_connect_ex(self):
1508 # Issue #11326: check connect_ex() implementation
Christian Heimesd0486372016-09-10 23:23:33 +02001509 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001510 cert_reqs=ssl.CERT_REQUIRED,
1511 ca_certs=SIGNING_CA)
1512 self.addCleanup(s.close)
1513 self.assertEqual(0, s.connect_ex(self.server_addr))
1514 self.assertTrue(s.getpeercert())
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001515
1516 def test_non_blocking_connect_ex(self):
1517 # Issue #11326: non-blocking connect_ex() should allow handshake
1518 # to proceed after the socket gets ready.
Christian Heimesd0486372016-09-10 23:23:33 +02001519 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001520 cert_reqs=ssl.CERT_REQUIRED,
1521 ca_certs=SIGNING_CA,
1522 do_handshake_on_connect=False)
1523 self.addCleanup(s.close)
1524 s.setblocking(False)
1525 rc = s.connect_ex(self.server_addr)
1526 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1527 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
1528 # Wait for connect to finish
1529 select.select([], [s], [], 5.0)
1530 # Non-blocking handshake
1531 while True:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001532 try:
Martin Panter3840b2a2016-03-27 01:53:46 +00001533 s.do_handshake()
1534 break
1535 except ssl.SSLWantReadError:
1536 select.select([s], [], [], 5.0)
1537 except ssl.SSLWantWriteError:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001538 select.select([], [s], [], 5.0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001539 # SSL established
1540 self.assertTrue(s.getpeercert())
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001541
Antoine Pitrou152efa22010-05-16 18:19:27 +00001542 def test_connect_with_context(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001543 # Same as test_connect, but with a separately created context
1544 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1545 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1546 s.connect(self.server_addr)
1547 self.assertEqual({}, s.getpeercert())
1548 # Same with a server hostname
1549 with ctx.wrap_socket(socket.socket(socket.AF_INET),
1550 server_hostname="dummy") as s:
1551 s.connect(self.server_addr)
1552 ctx.verify_mode = ssl.CERT_REQUIRED
1553 # This should succeed because we specify the root cert
1554 ctx.load_verify_locations(SIGNING_CA)
1555 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1556 s.connect(self.server_addr)
1557 cert = s.getpeercert()
1558 self.assertTrue(cert)
1559
1560 def test_connect_with_context_fail(self):
1561 # This should fail because we have no verification certs. Connection
1562 # failure crashes ThreadedEchoServer, so run this in an independent
1563 # test method.
1564 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1565 ctx.verify_mode = ssl.CERT_REQUIRED
1566 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1567 self.addCleanup(s.close)
1568 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1569 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001570
1571 def test_connect_capath(self):
1572 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001573 # NOTE: the subject hashing algorithm has been changed between
1574 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1575 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001576 # filename) for this test to be portable across OpenSSL releases.
Martin Panter3840b2a2016-03-27 01:53:46 +00001577 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1578 ctx.verify_mode = ssl.CERT_REQUIRED
1579 ctx.load_verify_locations(capath=CAPATH)
1580 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1581 s.connect(self.server_addr)
1582 cert = s.getpeercert()
1583 self.assertTrue(cert)
1584 # Same with a bytes `capath` argument
1585 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1586 ctx.verify_mode = ssl.CERT_REQUIRED
1587 ctx.load_verify_locations(capath=BYTES_CAPATH)
1588 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1589 s.connect(self.server_addr)
1590 cert = s.getpeercert()
1591 self.assertTrue(cert)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001592
Christian Heimesefff7062013-11-21 03:35:02 +01001593 def test_connect_cadata(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001594 with open(SIGNING_CA) as f:
Christian Heimesefff7062013-11-21 03:35:02 +01001595 pem = f.read()
1596 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panter3840b2a2016-03-27 01:53:46 +00001597 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1598 ctx.verify_mode = ssl.CERT_REQUIRED
1599 ctx.load_verify_locations(cadata=pem)
1600 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1601 s.connect(self.server_addr)
1602 cert = s.getpeercert()
1603 self.assertTrue(cert)
Christian Heimesefff7062013-11-21 03:35:02 +01001604
Martin Panter3840b2a2016-03-27 01:53:46 +00001605 # same with DER
1606 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1607 ctx.verify_mode = ssl.CERT_REQUIRED
1608 ctx.load_verify_locations(cadata=der)
1609 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1610 s.connect(self.server_addr)
1611 cert = s.getpeercert()
1612 self.assertTrue(cert)
Christian Heimesefff7062013-11-21 03:35:02 +01001613
Antoine Pitroue3220242010-04-24 11:13:53 +00001614 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1615 def test_makefile_close(self):
1616 # Issue #5238: creating a file-like object with makefile() shouldn't
1617 # delay closing the underlying "real socket" (here tested with its
1618 # file descriptor, hence skipping the test under Windows).
Christian Heimesd0486372016-09-10 23:23:33 +02001619 ss = test_wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3840b2a2016-03-27 01:53:46 +00001620 ss.connect(self.server_addr)
1621 fd = ss.fileno()
1622 f = ss.makefile()
1623 f.close()
1624 # The fd is still open
1625 os.read(fd, 0)
1626 # Closing the SSL socket should close the fd too
1627 ss.close()
1628 gc.collect()
1629 with self.assertRaises(OSError) as e:
Antoine Pitroue3220242010-04-24 11:13:53 +00001630 os.read(fd, 0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001631 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001632
Antoine Pitrou480a1242010-04-28 21:37:09 +00001633 def test_non_blocking_handshake(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001634 s = socket.socket(socket.AF_INET)
1635 s.connect(self.server_addr)
1636 s.setblocking(False)
Christian Heimesd0486372016-09-10 23:23:33 +02001637 s = test_wrap_socket(s,
Martin Panter3840b2a2016-03-27 01:53:46 +00001638 cert_reqs=ssl.CERT_NONE,
1639 do_handshake_on_connect=False)
1640 self.addCleanup(s.close)
1641 count = 0
1642 while True:
1643 try:
1644 count += 1
1645 s.do_handshake()
1646 break
1647 except ssl.SSLWantReadError:
1648 select.select([s], [], [])
1649 except ssl.SSLWantWriteError:
1650 select.select([], [s], [])
1651 if support.verbose:
1652 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001653
Antoine Pitrou480a1242010-04-28 21:37:09 +00001654 def test_get_server_certificate(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001655 _test_get_server_certificate(self, *self.server_addr, cert=SIGNING_CA)
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001656
Martin Panter3840b2a2016-03-27 01:53:46 +00001657 def test_get_server_certificate_fail(self):
1658 # Connection failure crashes ThreadedEchoServer, so run this in an
1659 # independent test method
1660 _test_get_server_certificate_fail(self, *self.server_addr)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001661
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001662 def test_ciphers(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001663 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001664 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1665 s.connect(self.server_addr)
Christian Heimesd0486372016-09-10 23:23:33 +02001666 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001667 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1668 s.connect(self.server_addr)
1669 # Error checking can happen at instantiation or when connecting
1670 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
1671 with socket.socket(socket.AF_INET) as sock:
Christian Heimesd0486372016-09-10 23:23:33 +02001672 s = test_wrap_socket(sock,
Martin Panter3840b2a2016-03-27 01:53:46 +00001673 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1674 s.connect(self.server_addr)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001675
Christian Heimes9a5395a2013-06-17 15:44:12 +02001676 def test_get_ca_certs_capath(self):
1677 # capath certs are loaded on request
Martin Panter3840b2a2016-03-27 01:53:46 +00001678 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1679 ctx.verify_mode = ssl.CERT_REQUIRED
1680 ctx.load_verify_locations(capath=CAPATH)
1681 self.assertEqual(ctx.get_ca_certs(), [])
1682 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1683 s.connect(self.server_addr)
1684 cert = s.getpeercert()
1685 self.assertTrue(cert)
1686 self.assertEqual(len(ctx.get_ca_certs()), 1)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001687
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 Panter3840b2a2016-03-27 01:53:46 +00001691 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1692 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1693 s = socket.socket(socket.AF_INET)
1694 with ctx1.wrap_socket(s) as ss:
1695 ss.connect(self.server_addr)
1696 self.assertIs(ss.context, ctx1)
1697 self.assertIs(ss._sslobj.context, ctx1)
1698 ss.context = ctx2
1699 self.assertIs(ss.context, ctx2)
1700 self.assertIs(ss._sslobj.context, ctx2)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001701
1702 def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs):
1703 # A simple IO loop. Call func(*args) depending on the error we get
1704 # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs.
1705 timeout = kwargs.get('timeout', 10)
1706 count = 0
1707 while True:
1708 errno = None
1709 count += 1
1710 try:
1711 ret = func(*args)
1712 except ssl.SSLError as e:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001713 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
Martin Panter40b97ec2016-01-14 13:05:46 +00001714 ssl.SSL_ERROR_WANT_WRITE):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001715 raise
1716 errno = e.errno
1717 # Get any data from the outgoing BIO irrespective of any error, and
1718 # send it to the socket.
1719 buf = outgoing.read()
1720 sock.sendall(buf)
1721 # If there's no error, we're done. For WANT_READ, we need to get
1722 # data from the socket and put it in the incoming BIO.
1723 if errno is None:
1724 break
1725 elif errno == ssl.SSL_ERROR_WANT_READ:
1726 buf = sock.recv(32768)
1727 if buf:
1728 incoming.write(buf)
1729 else:
1730 incoming.write_eof()
1731 if support.verbose:
1732 sys.stdout.write("Needed %d calls to complete %s().\n"
1733 % (count, func.__name__))
1734 return ret
1735
Martin Panter3840b2a2016-03-27 01:53:46 +00001736 def test_bio_handshake(self):
1737 sock = socket.socket(socket.AF_INET)
1738 self.addCleanup(sock.close)
1739 sock.connect(self.server_addr)
1740 incoming = ssl.MemoryBIO()
1741 outgoing = ssl.MemoryBIO()
1742 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1743 ctx.verify_mode = ssl.CERT_REQUIRED
1744 ctx.load_verify_locations(SIGNING_CA)
1745 ctx.check_hostname = True
1746 sslobj = ctx.wrap_bio(incoming, outgoing, False, 'localhost')
1747 self.assertIs(sslobj._sslobj.owner, sslobj)
1748 self.assertIsNone(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001749 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001750 self.assertRaises(ValueError, sslobj.getpeercert)
1751 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1752 self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
1753 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1754 self.assertTrue(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001755 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001756 self.assertTrue(sslobj.getpeercert())
1757 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1758 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
1759 try:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001760 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Martin Panter3840b2a2016-03-27 01:53:46 +00001761 except ssl.SSLSyscallError:
1762 # If the server shuts down the TCP connection without sending a
1763 # secure shutdown message, this is reported as SSL_ERROR_SYSCALL
1764 pass
1765 self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
1766
1767 def test_bio_read_write_data(self):
1768 sock = socket.socket(socket.AF_INET)
1769 self.addCleanup(sock.close)
1770 sock.connect(self.server_addr)
1771 incoming = ssl.MemoryBIO()
1772 outgoing = ssl.MemoryBIO()
1773 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1774 ctx.verify_mode = ssl.CERT_NONE
1775 sslobj = ctx.wrap_bio(incoming, outgoing, False)
1776 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1777 req = b'FOO\n'
1778 self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req)
1779 buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024)
1780 self.assertEqual(buf, b'foo\n')
1781 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001782
1783
Martin Panter3840b2a2016-03-27 01:53:46 +00001784class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001785
Martin Panter3840b2a2016-03-27 01:53:46 +00001786 def test_timeout_connect_ex(self):
1787 # Issue #12065: on a timeout, connect_ex() should return the original
1788 # errno (mimicking the behaviour of non-SSL sockets).
1789 with support.transient_internet(REMOTE_HOST):
Christian Heimesd0486372016-09-10 23:23:33 +02001790 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001791 cert_reqs=ssl.CERT_REQUIRED,
1792 do_handshake_on_connect=False)
1793 self.addCleanup(s.close)
1794 s.settimeout(0.0000001)
1795 rc = s.connect_ex((REMOTE_HOST, 443))
1796 if rc == 0:
1797 self.skipTest("REMOTE_HOST responded too quickly")
1798 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1799
1800 @unittest.skipUnless(support.IPV6_ENABLED, 'Needs IPv6')
1801 def test_get_server_certificate_ipv6(self):
1802 with support.transient_internet('ipv6.google.com'):
1803 _test_get_server_certificate(self, 'ipv6.google.com', 443)
1804 _test_get_server_certificate_fail(self, 'ipv6.google.com', 443)
1805
1806 def test_algorithms(self):
1807 # Issue #8484: all algorithms should be available when verifying a
1808 # certificate.
1809 # SHA256 was added in OpenSSL 0.9.8
1810 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1811 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
1812 # sha256.tbs-internet.com needs SNI to use the correct certificate
1813 if not ssl.HAS_SNI:
1814 self.skipTest("SNI needed for this test")
1815 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1816 remote = ("sha256.tbs-internet.com", 443)
1817 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
1818 with support.transient_internet("sha256.tbs-internet.com"):
1819 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1820 ctx.verify_mode = ssl.CERT_REQUIRED
1821 ctx.load_verify_locations(sha256_cert)
1822 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1823 server_hostname="sha256.tbs-internet.com")
1824 try:
1825 s.connect(remote)
1826 if support.verbose:
1827 sys.stdout.write("\nCipher with %r is %r\n" %
1828 (remote, s.cipher()))
1829 sys.stdout.write("Certificate is:\n%s\n" %
1830 pprint.pformat(s.getpeercert()))
1831 finally:
1832 s.close()
1833
1834
1835def _test_get_server_certificate(test, host, port, cert=None):
1836 pem = ssl.get_server_certificate((host, port))
1837 if not pem:
1838 test.fail("No server certificate on %s:%s!" % (host, port))
1839
1840 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
1841 if not pem:
1842 test.fail("No server certificate on %s:%s!" % (host, port))
1843 if support.verbose:
1844 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
1845
1846def _test_get_server_certificate_fail(test, host, port):
1847 try:
1848 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
1849 except ssl.SSLError as x:
1850 #should fail
1851 if support.verbose:
1852 sys.stdout.write("%s\n" % x)
1853 else:
1854 test.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1855
1856
1857if _have_threads:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001858 from test.ssl_servers import make_https_server
1859
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001860 class ThreadedEchoServer(threading.Thread):
1861
1862 class ConnectionHandler(threading.Thread):
1863
1864 """A mildly complicated class, because we want it to work both
1865 with and without the SSL wrapper around the socket connection, so
1866 that we can test the STARTTLS functionality."""
1867
Bill Janssen6e027db2007-11-15 22:23:56 +00001868 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001869 self.server = server
1870 self.running = False
1871 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001872 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001873 self.sock.setblocking(1)
1874 self.sslconn = None
1875 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001876 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001877
Antoine Pitrou480a1242010-04-28 21:37:09 +00001878 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001879 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001880 self.sslconn = self.server.context.wrap_socket(
1881 self.sock, server_side=True)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001882 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1883 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001884 except (ssl.SSLError, ConnectionResetError) as e:
1885 # We treat ConnectionResetError as though it were an
1886 # SSLError - OpenSSL on Ubuntu abruptly closes the
1887 # connection when asked to use an unsupported protocol.
1888 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001889 # XXX Various errors can have happened here, for example
1890 # a mismatching protocol version, an invalid certificate,
1891 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001892 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001893 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001894 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001895 self.running = False
1896 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001897 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001898 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001899 else:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001900 self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
Antoine Pitroub5218772010-05-21 09:56:06 +00001901 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001902 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001903 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001904 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1905 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001906 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001907 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1908 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001909 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001910 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001911 sys.stdout.write(" server: selected protocol is now "
1912 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001913 return True
1914
1915 def read(self):
1916 if self.sslconn:
1917 return self.sslconn.read()
1918 else:
1919 return self.sock.recv(1024)
1920
1921 def write(self, bytes):
1922 if self.sslconn:
1923 return self.sslconn.write(bytes)
1924 else:
1925 return self.sock.send(bytes)
1926
1927 def close(self):
1928 if self.sslconn:
1929 self.sslconn.close()
1930 else:
1931 self.sock.close()
1932
Antoine Pitrou480a1242010-04-28 21:37:09 +00001933 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001934 self.running = True
1935 if not self.server.starttls_server:
1936 if not self.wrap_conn():
1937 return
1938 while self.running:
1939 try:
1940 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001941 stripped = msg.strip()
1942 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001943 # eof, so quit this handler
1944 self.running = False
Martin Panter3840b2a2016-03-27 01:53:46 +00001945 try:
1946 self.sock = self.sslconn.unwrap()
1947 except OSError:
1948 # Many tests shut the TCP connection down
1949 # without an SSL shutdown. This causes
1950 # unwrap() to raise OSError with errno=0!
1951 pass
1952 else:
1953 self.sslconn = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001954 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001955 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001956 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001957 sys.stdout.write(" server: client closed connection\n")
1958 self.close()
1959 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001960 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001961 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001962 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001963 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001964 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001965 if not self.wrap_conn():
1966 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001967 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001968 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001969 if support.verbose and self.server.connectionchatty:
1970 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001971 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001972 self.sock = self.sslconn.unwrap()
1973 self.sslconn = None
1974 if support.verbose and self.server.connectionchatty:
1975 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001976 elif stripped == b'CB tls-unique':
1977 if support.verbose and self.server.connectionchatty:
1978 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1979 data = self.sslconn.get_channel_binding("tls-unique")
1980 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001981 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001982 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001983 self.server.connectionchatty):
1984 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001985 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1986 % (msg, ctype, msg.lower(), ctype))
1987 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001988 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001989 if self.server.chatty:
1990 handle_error("Test server failure:\n")
1991 self.close()
1992 self.running = False
1993 # normally, we'd just stop here, but for the test
1994 # harness, we want to stop the server
1995 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001996
Antoine Pitroub5218772010-05-21 09:56:06 +00001997 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001998 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001999 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersoncca27322015-01-23 16:35:37 -05002000 npn_protocols=None, alpn_protocols=None,
2001 ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00002002 if context:
2003 self.context = context
2004 else:
2005 self.context = ssl.SSLContext(ssl_version
2006 if ssl_version is not None
2007 else ssl.PROTOCOL_TLSv1)
2008 self.context.verify_mode = (certreqs if certreqs is not None
2009 else ssl.CERT_NONE)
2010 if cacerts:
2011 self.context.load_verify_locations(cacerts)
2012 if certificate:
2013 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002014 if npn_protocols:
2015 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05002016 if alpn_protocols:
2017 self.context.set_alpn_protocols(alpn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00002018 if ciphers:
2019 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002020 self.chatty = chatty
2021 self.connectionchatty = connectionchatty
2022 self.starttls_server = starttls_server
2023 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002024 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002025 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002026 self.active = False
Benjamin Petersoncca27322015-01-23 16:35:37 -05002027 self.selected_npn_protocols = []
2028 self.selected_alpn_protocols = []
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002029 self.shared_ciphers = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002030 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002031 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002032 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002033
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002034 def __enter__(self):
2035 self.start(threading.Event())
2036 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002037 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002038
2039 def __exit__(self, *args):
2040 self.stop()
2041 self.join()
2042
Antoine Pitrou480a1242010-04-28 21:37:09 +00002043 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002044 self.flag = flag
2045 threading.Thread.start(self)
2046
Antoine Pitrou480a1242010-04-28 21:37:09 +00002047 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00002048 self.sock.settimeout(0.05)
Charles-François Natali6e204602014-07-23 19:28:13 +01002049 self.sock.listen()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002050 self.active = True
2051 if self.flag:
2052 # signal an event
2053 self.flag.set()
2054 while self.active:
2055 try:
2056 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002057 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002058 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00002059 + repr(connaddr) + '\n')
2060 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002061 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01002062 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002063 except socket.timeout:
2064 pass
2065 except KeyboardInterrupt:
2066 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00002067 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002068
Antoine Pitrou480a1242010-04-28 21:37:09 +00002069 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002070 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002071
Bill Janssen54cc54c2007-12-14 22:08:56 +00002072 class AsyncoreEchoServer(threading.Thread):
2073
2074 # this one's based on asyncore.dispatcher
2075
2076 class EchoServer (asyncore.dispatcher):
2077
Victor Stinner1dae7452017-05-02 13:12:02 +02002078 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002079
2080 def __init__(self, conn, certfile):
Christian Heimesd0486372016-09-10 23:23:33 +02002081 self.socket = test_wrap_socket(conn, server_side=True,
Bill Janssen54cc54c2007-12-14 22:08:56 +00002082 certfile=certfile,
2083 do_handshake_on_connect=False)
2084 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002085 self._ssl_accepting = True
2086 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002087
2088 def readable(self):
2089 if isinstance(self.socket, ssl.SSLSocket):
2090 while self.socket.pending() > 0:
2091 self.handle_read_event()
2092 return True
2093
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002094 def _do_ssl_handshake(self):
2095 try:
2096 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02002097 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
2098 return
2099 except ssl.SSLEOFError:
2100 return self.handle_close()
2101 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002102 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002103 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002104 if err.args[0] == errno.ECONNABORTED:
2105 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002106 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002107 self._ssl_accepting = False
2108
2109 def handle_read(self):
2110 if self._ssl_accepting:
2111 self._do_ssl_handshake()
2112 else:
2113 data = self.recv(1024)
2114 if support.verbose:
2115 sys.stdout.write(" server: read %s from client\n" % repr(data))
2116 if not data:
2117 self.close()
2118 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002119 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00002120
2121 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00002122 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002123 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002124 sys.stdout.write(" server: closed connection %s\n" % self.socket)
2125
2126 def handle_error(self):
2127 raise
2128
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002129 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002130 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002131 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2132 self.port = support.bind_port(sock, '')
2133 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00002134 self.listen(5)
2135
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00002136 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002137 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002138 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
2139 self.ConnectionHandler(sock_obj, self.certfile)
2140
2141 def handle_error(self):
2142 raise
2143
Trent Nelson78520002008-04-10 20:54:35 +00002144 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002145 self.flag = None
2146 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002147 self.server = self.EchoServer(certfile)
2148 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00002149 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002150 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00002151
2152 def __str__(self):
2153 return "<%s %s>" % (self.__class__.__name__, self.server)
2154
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002155 def __enter__(self):
2156 self.start(threading.Event())
2157 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002158 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002159
2160 def __exit__(self, *args):
2161 if support.verbose:
2162 sys.stdout.write(" cleanup: stopping server.\n")
2163 self.stop()
2164 if support.verbose:
2165 sys.stdout.write(" cleanup: joining server thread.\n")
2166 self.join()
2167 if support.verbose:
2168 sys.stdout.write(" cleanup: successfully joined.\n")
Victor Stinner1dae7452017-05-02 13:12:02 +02002169 # make sure that ConnectionHandler is removed from socket_map
2170 asyncore.close_all(ignore_all=True)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002171
Bill Janssen54cc54c2007-12-14 22:08:56 +00002172 def start (self, flag=None):
2173 self.flag = flag
2174 threading.Thread.start(self)
2175
Antoine Pitrou480a1242010-04-28 21:37:09 +00002176 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002177 self.active = True
2178 if self.flag:
2179 self.flag.set()
2180 while self.active:
2181 try:
2182 asyncore.loop(1)
2183 except:
2184 pass
2185
Antoine Pitrou480a1242010-04-28 21:37:09 +00002186 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002187 self.active = False
2188 self.server.close()
2189
Antoine Pitroub5218772010-05-21 09:56:06 +00002190 def server_params_test(client_context, server_context, indata=b"FOO\n",
Christian Heimes99a65702016-09-10 23:44:53 +02002191 chatty=True, connectionchatty=False, sni_name=None,
2192 session=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00002193 """
2194 Launch a server, connect a client to it and try various reads
2195 and writes.
2196 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002197 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00002198 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002199 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00002200 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002201 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002202 with client_context.wrap_socket(socket.socket(),
Christian Heimes99a65702016-09-10 23:44:53 +02002203 server_hostname=sni_name, session=session) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002204 s.connect((HOST, server.port))
2205 for arg in [indata, bytearray(indata), memoryview(indata)]:
2206 if connectionchatty:
2207 if support.verbose:
2208 sys.stdout.write(
2209 " client: sending %r...\n" % indata)
2210 s.write(arg)
2211 outdata = s.read()
2212 if connectionchatty:
2213 if support.verbose:
2214 sys.stdout.write(" client: read %r\n" % outdata)
2215 if outdata != indata.lower():
2216 raise AssertionError(
2217 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2218 % (outdata[:20], len(outdata),
2219 indata[:20].lower(), len(indata)))
2220 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00002221 if connectionchatty:
2222 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002223 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002224 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01002225 'compression': s.compression(),
2226 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002227 'peercert': s.getpeercert(),
Benjamin Petersoncca27322015-01-23 16:35:37 -05002228 'client_alpn_protocol': s.selected_alpn_protocol(),
Antoine Pitrou47e40422014-09-04 21:00:10 +02002229 'client_npn_protocol': s.selected_npn_protocol(),
2230 'version': s.version(),
Christian Heimes99a65702016-09-10 23:44:53 +02002231 'session_reused': s.session_reused,
2232 'session': s.session,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002233 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01002234 s.close()
Benjamin Petersoncca27322015-01-23 16:35:37 -05002235 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2236 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002237 stats['server_shared_ciphers'] = server.shared_ciphers
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002238 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00002239
Antoine Pitroub5218772010-05-21 09:56:06 +00002240 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2241 certsreqs=None, server_options=0, client_options=0):
Antoine Pitrou47e40422014-09-04 21:00:10 +02002242 """
2243 Try to SSL-connect using *client_protocol* to *server_protocol*.
2244 If *expect_success* is true, assert that the connection succeeds,
2245 if it's false, assert that the connection fails.
2246 Also, if *expect_success* is a string, assert that it is the protocol
2247 version actually used by the connection.
2248 """
Benjamin Peterson2a691a82008-03-31 01:51:45 +00002249 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002250 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00002251 certtype = {
2252 ssl.CERT_NONE: "CERT_NONE",
2253 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2254 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2255 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002256 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002257 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002258 sys.stdout.write(formatstr %
2259 (ssl.get_protocol_name(client_protocol),
2260 ssl.get_protocol_name(server_protocol),
2261 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00002262 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002263 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00002264 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002265 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002266
2267 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2268 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2269 # starting from OpenSSL 1.0.0 (see issue #8322).
2270 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2271 client_context.set_ciphers("ALL")
2272
Antoine Pitroub5218772010-05-21 09:56:06 +00002273 for ctx in (client_context, server_context):
2274 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00002275 ctx.load_cert_chain(CERTFILE)
2276 ctx.load_verify_locations(CERTFILE)
2277 try:
Antoine Pitrou47e40422014-09-04 21:00:10 +02002278 stats = server_params_test(client_context, server_context,
2279 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002280 # Protocol mismatch can result in either an SSLError, or a
2281 # "Connection reset by peer" error.
2282 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002283 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002284 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002285 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002286 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002287 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002288 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002289 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00002290 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002291 "Client protocol %s succeeded with server protocol %s!"
2292 % (ssl.get_protocol_name(client_protocol),
2293 ssl.get_protocol_name(server_protocol)))
Antoine Pitrou47e40422014-09-04 21:00:10 +02002294 elif (expect_success is not True
2295 and expect_success != stats['version']):
2296 raise AssertionError("version mismatch: expected %r, got %r"
2297 % (expect_success, stats['version']))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002298
2299
Bill Janssen6e027db2007-11-15 22:23:56 +00002300 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002301
Antoine Pitrou23df4832010-08-04 17:14:06 +00002302 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002303 def test_echo(self):
2304 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002305 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002306 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002307 for protocol in PROTOCOLS:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002308 if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
2309 continue
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01002310 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
2311 context = ssl.SSLContext(protocol)
2312 context.load_cert_chain(CERTFILE)
2313 server_params_test(context, context,
2314 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002315
Christian Heimes5fe668c2016-09-12 00:01:11 +02002316 client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
2317 client_context.load_verify_locations(SIGNING_CA)
2318 server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
2319 # server_context.load_verify_locations(SIGNING_CA)
2320 server_context.load_cert_chain(SIGNED_CERTFILE2)
2321
Christian Heimes9017ec12016-09-12 10:48:20 +02002322 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_SERVER):
Christian Heimes5fe668c2016-09-12 00:01:11 +02002323 server_params_test(client_context=client_context,
2324 server_context=server_context,
2325 chatty=True, connectionchatty=True,
2326 sni_name='fakehostname')
2327
Christian Heimes9017ec12016-09-12 10:48:20 +02002328 client_context.check_hostname = False
2329 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT):
2330 with self.assertRaises(ssl.SSLError) as e:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002331 server_params_test(client_context=server_context,
2332 server_context=client_context,
2333 chatty=True, connectionchatty=True,
2334 sni_name='fakehostname')
Christian Heimes9017ec12016-09-12 10:48:20 +02002335 self.assertIn('called a function you should not call',
2336 str(e.exception))
2337
2338 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER):
2339 with self.assertRaises(ssl.SSLError) as e:
2340 server_params_test(client_context=server_context,
2341 server_context=server_context,
2342 chatty=True, connectionchatty=True)
2343 self.assertIn('called a function you should not call',
2344 str(e.exception))
2345
2346 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_CLIENT):
2347 with self.assertRaises(ssl.SSLError) as e:
2348 server_params_test(client_context=server_context,
2349 server_context=client_context,
2350 chatty=True, connectionchatty=True)
2351 self.assertIn('called a function you should not call',
2352 str(e.exception))
2353
Christian Heimes5fe668c2016-09-12 00:01:11 +02002354
Antoine Pitrou480a1242010-04-28 21:37:09 +00002355 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002356 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002357 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002358 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2359 context.verify_mode = ssl.CERT_REQUIRED
2360 context.load_verify_locations(CERTFILE)
2361 context.load_cert_chain(CERTFILE)
2362 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002363 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02002364 s = context.wrap_socket(socket.socket(),
2365 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002366 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02002367 # getpeercert() raise ValueError while the handshake isn't
2368 # done.
2369 with self.assertRaises(ValueError):
2370 s.getpeercert()
2371 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002372 cert = s.getpeercert()
2373 self.assertTrue(cert, "Can't get peer certificate.")
2374 cipher = s.cipher()
2375 if support.verbose:
2376 sys.stdout.write(pprint.pformat(cert) + '\n')
2377 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2378 if 'subject' not in cert:
2379 self.fail("No subject field in certificate: %s." %
2380 pprint.pformat(cert))
2381 if ((('organizationName', 'Python Software Foundation'),)
2382 not in cert['subject']):
2383 self.fail(
2384 "Missing or invalid 'organizationName' field in certificate subject; "
2385 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00002386 self.assertIn('notBefore', cert)
2387 self.assertIn('notAfter', cert)
2388 before = ssl.cert_time_to_seconds(cert['notBefore'])
2389 after = ssl.cert_time_to_seconds(cert['notAfter'])
2390 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002391 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002392
Christian Heimes2427b502013-11-23 11:24:32 +01002393 @unittest.skipUnless(have_verify_flags(),
2394 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01002395 def test_crl_check(self):
2396 if support.verbose:
2397 sys.stdout.write("\n")
2398
2399 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2400 server_context.load_cert_chain(SIGNED_CERTFILE)
2401
2402 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2403 context.verify_mode = ssl.CERT_REQUIRED
2404 context.load_verify_locations(SIGNING_CA)
Benjamin Petersonc3d9c5c2015-03-04 23:18:48 -05002405 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2406 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +01002407
2408 # VERIFY_DEFAULT should pass
2409 server = ThreadedEchoServer(context=server_context, chatty=True)
2410 with server:
2411 with context.wrap_socket(socket.socket()) as s:
2412 s.connect((HOST, server.port))
2413 cert = s.getpeercert()
2414 self.assertTrue(cert, "Can't get peer certificate.")
2415
2416 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01002417 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01002418
2419 server = ThreadedEchoServer(context=server_context, chatty=True)
2420 with server:
2421 with context.wrap_socket(socket.socket()) as s:
2422 with self.assertRaisesRegex(ssl.SSLError,
2423 "certificate verify failed"):
2424 s.connect((HOST, server.port))
2425
2426 # now load a CRL file. The CRL file is signed by the CA.
2427 context.load_verify_locations(CRLFILE)
2428
2429 server = ThreadedEchoServer(context=server_context, chatty=True)
2430 with server:
2431 with context.wrap_socket(socket.socket()) as s:
2432 s.connect((HOST, server.port))
2433 cert = s.getpeercert()
2434 self.assertTrue(cert, "Can't get peer certificate.")
2435
Christian Heimes1aa9a752013-12-02 02:41:19 +01002436 def test_check_hostname(self):
2437 if support.verbose:
2438 sys.stdout.write("\n")
2439
2440 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2441 server_context.load_cert_chain(SIGNED_CERTFILE)
2442
2443 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2444 context.verify_mode = ssl.CERT_REQUIRED
2445 context.check_hostname = True
2446 context.load_verify_locations(SIGNING_CA)
2447
2448 # correct hostname should verify
2449 server = ThreadedEchoServer(context=server_context, chatty=True)
2450 with server:
2451 with context.wrap_socket(socket.socket(),
2452 server_hostname="localhost") as s:
2453 s.connect((HOST, server.port))
2454 cert = s.getpeercert()
2455 self.assertTrue(cert, "Can't get peer certificate.")
2456
2457 # incorrect hostname should raise an exception
2458 server = ThreadedEchoServer(context=server_context, chatty=True)
2459 with server:
2460 with context.wrap_socket(socket.socket(),
2461 server_hostname="invalid") as s:
2462 with self.assertRaisesRegex(ssl.CertificateError,
2463 "hostname 'invalid' doesn't match 'localhost'"):
2464 s.connect((HOST, server.port))
2465
2466 # missing server_hostname arg should cause an exception, too
2467 server = ThreadedEchoServer(context=server_context, chatty=True)
2468 with server:
2469 with socket.socket() as s:
2470 with self.assertRaisesRegex(ValueError,
2471 "check_hostname requires server_hostname"):
2472 context.wrap_socket(s)
2473
Martin Panter407b62f2016-01-30 03:41:43 +00002474 def test_wrong_cert(self):
Martin Panter3464ea22016-02-01 21:58:11 +00002475 """Connecting when the server rejects the client's certificate
2476
2477 Launch a server with CERT_REQUIRED, and check that trying to
2478 connect to it with a wrong client certificate fails.
2479 """
2480 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2481 "wrongcert.pem")
2482 server = ThreadedEchoServer(CERTFILE,
2483 certreqs=ssl.CERT_REQUIRED,
2484 cacerts=CERTFILE, chatty=False,
2485 connectionchatty=False)
2486 with server, \
2487 socket.socket() as sock, \
Christian Heimesd0486372016-09-10 23:23:33 +02002488 test_wrap_socket(sock,
Martin Panter3464ea22016-02-01 21:58:11 +00002489 certfile=certfile,
2490 ssl_version=ssl.PROTOCOL_TLSv1) as s:
2491 try:
2492 # Expect either an SSL error about the server rejecting
2493 # the connection, or a low-level connection reset (which
2494 # sometimes happens on Windows)
2495 s.connect((HOST, server.port))
2496 except ssl.SSLError as e:
2497 if support.verbose:
2498 sys.stdout.write("\nSSLError is %r\n" % e)
2499 except OSError as e:
2500 if e.errno != errno.ECONNRESET:
2501 raise
2502 if support.verbose:
2503 sys.stdout.write("\nsocket.error is %r\n" % e)
2504 else:
2505 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002506
Antoine Pitrou480a1242010-04-28 21:37:09 +00002507 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002508 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002509 in the client when attempting handshake.
2510 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002511 listener_ready = threading.Event()
2512 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002513
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002514 s = socket.socket()
2515 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002516
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002517 # `listener` runs in a thread. It sits in an accept() until
2518 # the main thread connects. Then it rudely closes the socket,
2519 # and sets Event `listener_gone` to let the main thread know
2520 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002521 def listener():
Charles-François Natali6e204602014-07-23 19:28:13 +01002522 s.listen()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002523 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002524 newsock, addr = s.accept()
2525 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002526 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002527 listener_gone.set()
2528
2529 def connector():
2530 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002531 with socket.socket() as c:
2532 c.connect((HOST, port))
2533 listener_gone.wait()
2534 try:
Christian Heimesd0486372016-09-10 23:23:33 +02002535 ssl_sock = test_wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002536 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002537 pass
2538 else:
2539 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002540
2541 t = threading.Thread(target=listener)
2542 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002543 try:
2544 connector()
2545 finally:
2546 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002547
Antoine Pitrou23df4832010-08-04 17:14:06 +00002548 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002549 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2550 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002551 def test_protocol_sslv2(self):
2552 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002553 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002554 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002555 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2556 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2557 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002558 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Victor Stinner648b8622014-12-12 12:23:59 +01002559 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2560 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002561 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002562 # SSLv23 client with specific SSL options
2563 if no_sslv2_implies_sslv3_hello():
2564 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2565 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2566 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002567 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002568 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002569 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002570 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002571
Antoine Pitrou23df4832010-08-04 17:14:06 +00002572 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002573 def test_protocol_sslv23(self):
2574 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002575 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002576 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002577 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2578 try:
2579 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002580 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002581 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2582 if support.verbose:
2583 sys.stdout.write(
2584 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2585 % str(x))
Benjamin Petersone32467c2014-12-05 21:59:35 -05002586 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002587 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002588 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002589 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002590
Benjamin Petersone32467c2014-12-05 21:59:35 -05002591 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002592 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002593 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002594 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002595
Benjamin Petersone32467c2014-12-05 21:59:35 -05002596 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002597 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002598 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002599 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002600
Antoine Pitroub5218772010-05-21 09:56:06 +00002601 # Server with specific SSL options
Benjamin Petersone32467c2014-12-05 21:59:35 -05002602 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2603 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002604 server_options=ssl.OP_NO_SSLv3)
2605 # Will choose TLSv1
2606 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2607 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2608 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2609 server_options=ssl.OP_NO_TLSv1)
2610
2611
Antoine Pitrou23df4832010-08-04 17:14:06 +00002612 @skip_if_broken_ubuntu_ssl
Benjamin Petersone32467c2014-12-05 21:59:35 -05002613 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2614 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002615 def test_protocol_sslv3(self):
2616 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002617 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002618 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002619 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2620 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2621 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002622 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2623 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002624 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2625 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002626 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002627 if no_sslv2_implies_sslv3_hello():
2628 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002629 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2630 False, client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002631
Antoine Pitrou23df4832010-08-04 17:14:06 +00002632 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002633 def test_protocol_tlsv1(self):
2634 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002635 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002636 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002637 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2638 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2639 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002640 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2641 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002642 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2643 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002644 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2645 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002646
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002647 @skip_if_broken_ubuntu_ssl
2648 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2649 "TLS version 1.1 not supported.")
2650 def test_protocol_tlsv1_1(self):
2651 """Connecting to a TLSv1.1 server with various client options.
2652 Testing against older TLS versions."""
2653 if support.verbose:
2654 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002655 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002656 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2657 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002658 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2659 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002660 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2661 client_options=ssl.OP_NO_TLSv1_1)
2662
Antoine Pitrou47e40422014-09-04 21:00:10 +02002663 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002664 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2665 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2666
2667
2668 @skip_if_broken_ubuntu_ssl
2669 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2670 "TLS version 1.2 not supported.")
2671 def test_protocol_tlsv1_2(self):
2672 """Connecting to a TLSv1.2 server with various client options.
2673 Testing against older TLS versions."""
2674 if support.verbose:
2675 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002676 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002677 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2678 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2679 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2680 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002681 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2682 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002683 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2684 client_options=ssl.OP_NO_TLSv1_2)
2685
Antoine Pitrou47e40422014-09-04 21:00:10 +02002686 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002687 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2688 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2689 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2690 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2691
Antoine Pitrou480a1242010-04-28 21:37:09 +00002692 def test_starttls(self):
2693 """Switching from clear text to encrypted and back again."""
2694 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 +00002695
Trent Nelson78520002008-04-10 20:54:35 +00002696 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002697 ssl_version=ssl.PROTOCOL_TLSv1,
2698 starttls_server=True,
2699 chatty=True,
2700 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002701 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002702 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002703 s = socket.socket()
2704 s.setblocking(1)
2705 s.connect((HOST, server.port))
2706 if support.verbose:
2707 sys.stdout.write("\n")
2708 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002709 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002710 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002711 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002712 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002713 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002714 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002715 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002716 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002717 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002718 msg = outdata.strip().lower()
2719 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2720 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002721 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002722 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002723 " client: read %r from server, starting TLS...\n"
2724 % msg)
Christian Heimesd0486372016-09-10 23:23:33 +02002725 conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002726 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002727 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2728 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002729 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002730 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002731 " client: read %r from server, ending TLS...\n"
2732 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002733 s = conn.unwrap()
2734 wrapped = False
2735 else:
2736 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002737 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002738 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002739 if support.verbose:
2740 sys.stdout.write(" client: closing connection.\n")
2741 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002742 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002743 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002744 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002745 if wrapped:
2746 conn.close()
2747 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002748 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002749
Antoine Pitrou480a1242010-04-28 21:37:09 +00002750 def test_socketserver(self):
Martin Panter463ef2b2016-09-22 09:37:56 +00002751 """Using socketserver to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002752 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002753 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002754 if support.verbose:
2755 sys.stdout.write('\n')
2756 with open(CERTFILE, 'rb') as f:
2757 d1 = f.read()
2758 d2 = ''
2759 # now fetch the same data from the HTTPS server
Benjamin Peterson4ffb0752014-11-03 14:29:33 -05002760 url = 'https://localhost:%d/%s' % (
2761 server.port, os.path.split(CERTFILE)[1])
2762 context = ssl.create_default_context(cafile=CERTFILE)
2763 f = urllib.request.urlopen(url, context=context)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002764 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002765 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002766 if dlen and (int(dlen) > 0):
2767 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002768 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002769 sys.stdout.write(
2770 " client: read %d bytes from remote server '%s'\n"
2771 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002772 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002773 f.close()
2774 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002775
Antoine Pitrou480a1242010-04-28 21:37:09 +00002776 def test_asyncore_server(self):
2777 """Check the example asyncore integration."""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002778 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002779 sys.stdout.write("\n")
2780
Antoine Pitrou480a1242010-04-28 21:37:09 +00002781 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002782 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002783 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002784 s = test_wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002785 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002786 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002787 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002788 " client: sending %r...\n" % indata)
2789 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002790 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002791 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002792 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002793 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002794 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002795 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2796 % (outdata[:20], len(outdata),
2797 indata[:20].lower(), len(indata)))
2798 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002799 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002800 sys.stdout.write(" client: closing connection.\n")
2801 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002802 if support.verbose:
2803 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002804
Antoine Pitrou480a1242010-04-28 21:37:09 +00002805 def test_recv_send(self):
2806 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002807 if support.verbose:
2808 sys.stdout.write("\n")
2809
2810 server = ThreadedEchoServer(CERTFILE,
2811 certreqs=ssl.CERT_NONE,
2812 ssl_version=ssl.PROTOCOL_TLSv1,
2813 cacerts=CERTFILE,
2814 chatty=True,
2815 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002816 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002817 s = test_wrap_socket(socket.socket(),
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002818 server_side=False,
2819 certfile=CERTFILE,
2820 ca_certs=CERTFILE,
2821 cert_reqs=ssl.CERT_NONE,
2822 ssl_version=ssl.PROTOCOL_TLSv1)
2823 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002824 # helper methods for standardising recv* method signatures
2825 def _recv_into():
2826 b = bytearray(b"\0"*100)
2827 count = s.recv_into(b)
2828 return b[:count]
2829
2830 def _recvfrom_into():
2831 b = bytearray(b"\0"*100)
2832 count, addr = s.recvfrom_into(b)
2833 return b[:count]
2834
Martin Panter519f9122016-04-03 02:12:54 +00002835 # (name, method, expect success?, *args, return value func)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002836 send_methods = [
Martin Panter519f9122016-04-03 02:12:54 +00002837 ('send', s.send, True, [], len),
2838 ('sendto', s.sendto, False, ["some.address"], len),
2839 ('sendall', s.sendall, True, [], lambda x: None),
Bill Janssen58afe4c2008-09-08 16:45:19 +00002840 ]
Martin Panter519f9122016-04-03 02:12:54 +00002841 # (name, method, whether to expect success, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002842 recv_methods = [
2843 ('recv', s.recv, True, []),
2844 ('recvfrom', s.recvfrom, False, ["some.address"]),
2845 ('recv_into', _recv_into, True, []),
2846 ('recvfrom_into', _recvfrom_into, False, []),
2847 ]
2848 data_prefix = "PREFIX_"
2849
Martin Panter519f9122016-04-03 02:12:54 +00002850 for (meth_name, send_meth, expect_success, args,
2851 ret_val_meth) in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002852 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002853 try:
Martin Panter519f9122016-04-03 02:12:54 +00002854 ret = send_meth(indata, *args)
2855 msg = "sending with {}".format(meth_name)
2856 self.assertEqual(ret, ret_val_meth(indata), msg=msg)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002857 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002858 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002859 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002860 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002861 "<<{outdata:r}>> ({nout:d}) received; "
2862 "expected <<{indata:r}>> ({nin:d})\n".format(
2863 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002864 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002865 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002866 )
2867 )
2868 except ValueError as e:
2869 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002870 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002871 "Failed to send with method <<{name:s}>>; "
2872 "expected to succeed.\n".format(name=meth_name)
2873 )
2874 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002875 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002876 "Method <<{name:s}>> failed with unexpected "
2877 "exception message: {exp:s}\n".format(
2878 name=meth_name, exp=e
2879 )
2880 )
2881
2882 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002883 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002884 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002885 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002886 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002887 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002888 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002889 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002890 "<<{outdata:r}>> ({nout:d}) received; "
2891 "expected <<{indata:r}>> ({nin:d})\n".format(
2892 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002893 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002894 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002895 )
2896 )
2897 except ValueError as e:
2898 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002899 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002900 "Failed to receive with method <<{name:s}>>; "
2901 "expected to succeed.\n".format(name=meth_name)
2902 )
2903 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002904 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002905 "Method <<{name:s}>> failed with unexpected "
2906 "exception message: {exp:s}\n".format(
2907 name=meth_name, exp=e
2908 )
2909 )
2910 # consume data
2911 s.read()
2912
Martin Panterf6b1d662016-03-28 00:22:09 +00002913 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panterbed7f1a2016-07-11 00:17:13 +00002914 data = b"data"
Martin Panter5503d472016-03-27 05:35:19 +00002915 s.send(data)
2916 buffer = bytearray(len(data))
2917 self.assertEqual(s.read(-1, buffer), len(data))
2918 self.assertEqual(buffer, data)
2919
Nick Coghlan513886a2011-08-28 00:00:27 +10002920 # Make sure sendmsg et al are disallowed to avoid
2921 # inadvertent disclosure of data and/or corruption
2922 # of the encrypted data stream
2923 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2924 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2925 self.assertRaises(NotImplementedError,
2926 s.recvmsg_into, bytearray(100))
2927
Antoine Pitrou480a1242010-04-28 21:37:09 +00002928 s.write(b"over\n")
Martin Panter5503d472016-03-27 05:35:19 +00002929
2930 self.assertRaises(ValueError, s.recv, -1)
2931 self.assertRaises(ValueError, s.read, -1)
2932
Bill Janssen58afe4c2008-09-08 16:45:19 +00002933 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002934
Martin Panterbed7f1a2016-07-11 00:17:13 +00002935 def test_recv_zero(self):
2936 server = ThreadedEchoServer(CERTFILE)
2937 server.__enter__()
2938 self.addCleanup(server.__exit__, None, None)
2939 s = socket.create_connection((HOST, server.port))
2940 self.addCleanup(s.close)
Christian Heimesd0486372016-09-10 23:23:33 +02002941 s = test_wrap_socket(s, suppress_ragged_eofs=False)
Martin Panterbed7f1a2016-07-11 00:17:13 +00002942 self.addCleanup(s.close)
2943
2944 # recv/read(0) should return no data
2945 s.send(b"data")
2946 self.assertEqual(s.recv(0), b"")
2947 self.assertEqual(s.read(0), b"")
2948 self.assertEqual(s.read(), b"data")
2949
2950 # Should not block if the other end sends no data
2951 s.setblocking(False)
2952 self.assertEqual(s.recv(0), b"")
2953 self.assertEqual(s.recv_into(bytearray()), 0)
2954
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002955 def test_nonblocking_send(self):
2956 server = ThreadedEchoServer(CERTFILE,
2957 certreqs=ssl.CERT_NONE,
2958 ssl_version=ssl.PROTOCOL_TLSv1,
2959 cacerts=CERTFILE,
2960 chatty=True,
2961 connectionchatty=False)
2962 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002963 s = test_wrap_socket(socket.socket(),
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002964 server_side=False,
2965 certfile=CERTFILE,
2966 ca_certs=CERTFILE,
2967 cert_reqs=ssl.CERT_NONE,
2968 ssl_version=ssl.PROTOCOL_TLSv1)
2969 s.connect((HOST, server.port))
2970 s.setblocking(False)
2971
2972 # If we keep sending data, at some point the buffers
2973 # will be full and the call will block
2974 buf = bytearray(8192)
2975 def fill_buffer():
2976 while True:
2977 s.send(buf)
2978 self.assertRaises((ssl.SSLWantWriteError,
2979 ssl.SSLWantReadError), fill_buffer)
2980
2981 # Now read all the output and discard it
2982 s.setblocking(True)
2983 s.close()
2984
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002985 def test_handshake_timeout(self):
2986 # Issue #5103: SSL handshake must respect the socket timeout
2987 server = socket.socket(socket.AF_INET)
2988 host = "127.0.0.1"
2989 port = support.bind_port(server)
2990 started = threading.Event()
2991 finish = False
2992
2993 def serve():
Charles-François Natali6e204602014-07-23 19:28:13 +01002994 server.listen()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002995 started.set()
2996 conns = []
2997 while not finish:
2998 r, w, e = select.select([server], [], [], 0.1)
2999 if server in r:
3000 # Let the socket hang around rather than having
3001 # it closed by garbage collection.
3002 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00003003 for sock in conns:
3004 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003005
3006 t = threading.Thread(target=serve)
3007 t.start()
3008 started.wait()
3009
3010 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00003011 try:
3012 c = socket.socket(socket.AF_INET)
3013 c.settimeout(0.2)
3014 c.connect((host, port))
3015 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003016 self.assertRaisesRegex(socket.timeout, "timed out",
Christian Heimesd0486372016-09-10 23:23:33 +02003017 test_wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00003018 finally:
3019 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003020 try:
3021 c = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +02003022 c = test_wrap_socket(c)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003023 c.settimeout(0.2)
3024 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003025 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00003026 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003027 finally:
3028 c.close()
3029 finally:
3030 finish = True
3031 t.join()
3032 server.close()
3033
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003034 def test_server_accept(self):
3035 # Issue #16357: accept() on a SSLSocket created through
3036 # SSLContext.wrap_socket().
3037 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3038 context.verify_mode = ssl.CERT_REQUIRED
3039 context.load_verify_locations(CERTFILE)
3040 context.load_cert_chain(CERTFILE)
3041 server = socket.socket(socket.AF_INET)
3042 host = "127.0.0.1"
3043 port = support.bind_port(server)
3044 server = context.wrap_socket(server, server_side=True)
Christian Heimesa5d07652016-09-24 10:48:05 +02003045 self.assertTrue(server.server_side)
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003046
3047 evt = threading.Event()
3048 remote = None
3049 peer = None
3050 def serve():
3051 nonlocal remote, peer
Charles-François Natali6e204602014-07-23 19:28:13 +01003052 server.listen()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003053 # Block on the accept and wait on the connection to close.
3054 evt.set()
3055 remote, peer = server.accept()
3056 remote.recv(1)
3057
3058 t = threading.Thread(target=serve)
3059 t.start()
3060 # Client wait until server setup and perform a connect.
3061 evt.wait()
3062 client = context.wrap_socket(socket.socket())
3063 client.connect((host, port))
3064 client_addr = client.getsockname()
3065 client.close()
3066 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003067 remote.close()
3068 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003069 # Sanity checks.
3070 self.assertIsInstance(remote, ssl.SSLSocket)
3071 self.assertEqual(peer, client_addr)
3072
Antoine Pitrou242db722013-05-01 20:52:07 +02003073 def test_getpeercert_enotconn(self):
3074 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3075 with context.wrap_socket(socket.socket()) as sock:
3076 with self.assertRaises(OSError) as cm:
3077 sock.getpeercert()
3078 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3079
3080 def test_do_handshake_enotconn(self):
3081 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3082 with context.wrap_socket(socket.socket()) as sock:
3083 with self.assertRaises(OSError) as cm:
3084 sock.do_handshake()
3085 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3086
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003087 def test_default_ciphers(self):
3088 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3089 try:
3090 # Force a set of weak ciphers on our client context
3091 context.set_ciphers("DES")
3092 except ssl.SSLError:
3093 self.skipTest("no DES cipher available")
3094 with ThreadedEchoServer(CERTFILE,
3095 ssl_version=ssl.PROTOCOL_SSLv23,
3096 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003097 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02003098 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003099 s.connect((HOST, server.port))
3100 self.assertIn("no shared cipher", str(server.conn_errors[0]))
3101
Antoine Pitrou47e40422014-09-04 21:00:10 +02003102 def test_version_basic(self):
3103 """
3104 Basic tests for SSLSocket.version().
3105 More tests are done in the test_protocol_*() methods.
3106 """
3107 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3108 with ThreadedEchoServer(CERTFILE,
3109 ssl_version=ssl.PROTOCOL_TLSv1,
3110 chatty=False) as server:
3111 with context.wrap_socket(socket.socket()) as s:
3112 self.assertIs(s.version(), None)
3113 s.connect((HOST, server.port))
Christian Heimes598894f2016-09-05 23:19:05 +02003114 self.assertEqual(s.version(), 'TLSv1')
Antoine Pitrou47e40422014-09-04 21:00:10 +02003115 self.assertIs(s.version(), None)
3116
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003117 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
3118 def test_default_ecdh_curve(self):
3119 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
3120 # should be enabled by default on SSL contexts.
3121 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3122 context.load_cert_chain(CERTFILE)
Antoine Pitrouc0430612014-04-16 18:33:39 +02003123 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
3124 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
3125 # our default cipher list should prefer ECDH-based ciphers
3126 # automatically.
3127 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
3128 context.set_ciphers("ECCdraft:ECDH")
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003129 with ThreadedEchoServer(context=context) as server:
3130 with context.wrap_socket(socket.socket()) as s:
3131 s.connect((HOST, server.port))
3132 self.assertIn("ECDH", s.cipher()[0])
3133
Antoine Pitroud6494802011-07-21 01:11:30 +02003134 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
3135 "'tls-unique' channel binding not available")
3136 def test_tls_unique_channel_binding(self):
3137 """Test tls-unique channel binding."""
3138 if support.verbose:
3139 sys.stdout.write("\n")
3140
3141 server = ThreadedEchoServer(CERTFILE,
3142 certreqs=ssl.CERT_NONE,
3143 ssl_version=ssl.PROTOCOL_TLSv1,
3144 cacerts=CERTFILE,
3145 chatty=True,
3146 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003147 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02003148 s = test_wrap_socket(socket.socket(),
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003149 server_side=False,
3150 certfile=CERTFILE,
3151 ca_certs=CERTFILE,
3152 cert_reqs=ssl.CERT_NONE,
3153 ssl_version=ssl.PROTOCOL_TLSv1)
3154 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02003155 # get the data
3156 cb_data = s.get_channel_binding("tls-unique")
3157 if support.verbose:
3158 sys.stdout.write(" got channel binding data: {0!r}\n"
3159 .format(cb_data))
3160
3161 # check if it is sane
3162 self.assertIsNotNone(cb_data)
3163 self.assertEqual(len(cb_data), 12) # True for TLSv1
3164
3165 # and compare with the peers version
3166 s.write(b"CB tls-unique\n")
3167 peer_data_repr = s.read().strip()
3168 self.assertEqual(peer_data_repr,
3169 repr(cb_data).encode("us-ascii"))
3170 s.close()
3171
3172 # now, again
Christian Heimesd0486372016-09-10 23:23:33 +02003173 s = test_wrap_socket(socket.socket(),
Antoine Pitroud6494802011-07-21 01:11:30 +02003174 server_side=False,
3175 certfile=CERTFILE,
3176 ca_certs=CERTFILE,
3177 cert_reqs=ssl.CERT_NONE,
3178 ssl_version=ssl.PROTOCOL_TLSv1)
3179 s.connect((HOST, server.port))
3180 new_cb_data = s.get_channel_binding("tls-unique")
3181 if support.verbose:
3182 sys.stdout.write(" got another channel binding data: {0!r}\n"
3183 .format(new_cb_data))
3184 # is it really unique
3185 self.assertNotEqual(cb_data, new_cb_data)
3186 self.assertIsNotNone(cb_data)
3187 self.assertEqual(len(cb_data), 12) # True for TLSv1
3188 s.write(b"CB tls-unique\n")
3189 peer_data_repr = s.read().strip()
3190 self.assertEqual(peer_data_repr,
3191 repr(new_cb_data).encode("us-ascii"))
3192 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00003193
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003194 def test_compression(self):
3195 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3196 context.load_cert_chain(CERTFILE)
3197 stats = server_params_test(context, context,
3198 chatty=True, connectionchatty=True)
3199 if support.verbose:
3200 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
3201 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
3202
3203 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
3204 "ssl.OP_NO_COMPRESSION needed for this test")
3205 def test_compression_disabled(self):
3206 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3207 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01003208 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003209 stats = server_params_test(context, context,
3210 chatty=True, connectionchatty=True)
3211 self.assertIs(stats['compression'], None)
3212
Antoine Pitrou0e576f12011-12-22 10:03:38 +01003213 def test_dh_params(self):
3214 # Check we can get a connection with ephemeral Diffie-Hellman
3215 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3216 context.load_cert_chain(CERTFILE)
3217 context.load_dh_params(DHFILE)
3218 context.set_ciphers("kEDH")
3219 stats = server_params_test(context, context,
3220 chatty=True, connectionchatty=True)
3221 cipher = stats["cipher"][0]
3222 parts = cipher.split("-")
3223 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
3224 self.fail("Non-DH cipher: " + cipher[0])
3225
Benjamin Petersoncca27322015-01-23 16:35:37 -05003226 def test_selected_alpn_protocol(self):
3227 # selected_alpn_protocol() is None unless ALPN is used.
3228 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3229 context.load_cert_chain(CERTFILE)
3230 stats = server_params_test(context, context,
3231 chatty=True, connectionchatty=True)
3232 self.assertIs(stats['client_alpn_protocol'], None)
3233
3234 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
3235 def test_selected_alpn_protocol_if_server_uses_alpn(self):
3236 # selected_alpn_protocol() is None unless ALPN is used by the client.
3237 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3238 client_context.load_verify_locations(CERTFILE)
3239 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3240 server_context.load_cert_chain(CERTFILE)
3241 server_context.set_alpn_protocols(['foo', 'bar'])
3242 stats = server_params_test(client_context, server_context,
3243 chatty=True, connectionchatty=True)
3244 self.assertIs(stats['client_alpn_protocol'], None)
3245
3246 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
3247 def test_alpn_protocols(self):
3248 server_protocols = ['foo', 'bar', 'milkshake']
3249 protocol_tests = [
3250 (['foo', 'bar'], 'foo'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003251 (['bar', 'foo'], 'foo'),
Benjamin Petersoncca27322015-01-23 16:35:37 -05003252 (['milkshake'], 'milkshake'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003253 (['http/3.0', 'http/4.0'], None)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003254 ]
3255 for client_protocols, expected in protocol_tests:
Christian Heimes598894f2016-09-05 23:19:05 +02003256 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003257 server_context.load_cert_chain(CERTFILE)
3258 server_context.set_alpn_protocols(server_protocols)
Christian Heimes598894f2016-09-05 23:19:05 +02003259 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003260 client_context.load_cert_chain(CERTFILE)
3261 client_context.set_alpn_protocols(client_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003262
Christian Heimes598894f2016-09-05 23:19:05 +02003263 try:
3264 stats = server_params_test(client_context,
3265 server_context,
3266 chatty=True,
3267 connectionchatty=True)
3268 except ssl.SSLError as e:
3269 stats = e
3270
Christian Heimes7b40cb72017-08-15 10:33:43 +02003271 if (expected is None and IS_OPENSSL_1_1
3272 and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)):
3273 # OpenSSL 1.1.0 to 1.1.0e raises handshake error
Christian Heimes598894f2016-09-05 23:19:05 +02003274 self.assertIsInstance(stats, ssl.SSLError)
3275 else:
3276 msg = "failed trying %s (s) and %s (c).\n" \
3277 "was expecting %s, but got %%s from the %%s" \
3278 % (str(server_protocols), str(client_protocols),
3279 str(expected))
3280 client_result = stats['client_alpn_protocol']
3281 self.assertEqual(client_result, expected,
3282 msg % (client_result, "client"))
3283 server_result = stats['server_alpn_protocols'][-1] \
3284 if len(stats['server_alpn_protocols']) else 'nothing'
3285 self.assertEqual(server_result, expected,
3286 msg % (server_result, "server"))
Benjamin Petersoncca27322015-01-23 16:35:37 -05003287
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01003288 def test_selected_npn_protocol(self):
3289 # selected_npn_protocol() is None unless NPN is used
3290 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3291 context.load_cert_chain(CERTFILE)
3292 stats = server_params_test(context, context,
3293 chatty=True, connectionchatty=True)
3294 self.assertIs(stats['client_npn_protocol'], None)
3295
3296 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
3297 def test_npn_protocols(self):
3298 server_protocols = ['http/1.1', 'spdy/2']
3299 protocol_tests = [
3300 (['http/1.1', 'spdy/2'], 'http/1.1'),
3301 (['spdy/2', 'http/1.1'], 'http/1.1'),
3302 (['spdy/2', 'test'], 'spdy/2'),
3303 (['abc', 'def'], 'abc')
3304 ]
3305 for client_protocols, expected in protocol_tests:
3306 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3307 server_context.load_cert_chain(CERTFILE)
3308 server_context.set_npn_protocols(server_protocols)
3309 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3310 client_context.load_cert_chain(CERTFILE)
3311 client_context.set_npn_protocols(client_protocols)
3312 stats = server_params_test(client_context, server_context,
3313 chatty=True, connectionchatty=True)
3314
3315 msg = "failed trying %s (s) and %s (c).\n" \
3316 "was expecting %s, but got %%s from the %%s" \
3317 % (str(server_protocols), str(client_protocols),
3318 str(expected))
3319 client_result = stats['client_npn_protocol']
3320 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3321 server_result = stats['server_npn_protocols'][-1] \
3322 if len(stats['server_npn_protocols']) else 'nothing'
3323 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3324
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003325 def sni_contexts(self):
3326 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3327 server_context.load_cert_chain(SIGNED_CERTFILE)
3328 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3329 other_context.load_cert_chain(SIGNED_CERTFILE2)
3330 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3331 client_context.verify_mode = ssl.CERT_REQUIRED
3332 client_context.load_verify_locations(SIGNING_CA)
3333 return server_context, other_context, client_context
3334
3335 def check_common_name(self, stats, name):
3336 cert = stats['peercert']
3337 self.assertIn((('commonName', name),), cert['subject'])
3338
3339 @needs_sni
3340 def test_sni_callback(self):
3341 calls = []
3342 server_context, other_context, client_context = self.sni_contexts()
3343
3344 def servername_cb(ssl_sock, server_name, initial_context):
3345 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003346 if server_name is not None:
3347 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003348 server_context.set_servername_callback(servername_cb)
3349
3350 stats = server_params_test(client_context, server_context,
3351 chatty=True,
3352 sni_name='supermessage')
3353 # The hostname was fetched properly, and the certificate was
3354 # changed for the connection.
3355 self.assertEqual(calls, [("supermessage", server_context)])
3356 # CERTFILE4 was selected
3357 self.check_common_name(stats, 'fakehostname')
3358
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003359 calls = []
3360 # The callback is called with server_name=None
3361 stats = server_params_test(client_context, server_context,
3362 chatty=True,
3363 sni_name=None)
3364 self.assertEqual(calls, [(None, server_context)])
3365 self.check_common_name(stats, 'localhost')
3366
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003367 # Check disabling the callback
3368 calls = []
3369 server_context.set_servername_callback(None)
3370
3371 stats = server_params_test(client_context, server_context,
3372 chatty=True,
3373 sni_name='notfunny')
3374 # Certificate didn't change
3375 self.check_common_name(stats, 'localhost')
3376 self.assertEqual(calls, [])
3377
3378 @needs_sni
3379 def test_sni_callback_alert(self):
3380 # Returning a TLS alert is reflected to the connecting client
3381 server_context, other_context, client_context = self.sni_contexts()
3382
3383 def cb_returning_alert(ssl_sock, server_name, initial_context):
3384 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3385 server_context.set_servername_callback(cb_returning_alert)
3386
3387 with self.assertRaises(ssl.SSLError) as cm:
3388 stats = server_params_test(client_context, server_context,
3389 chatty=False,
3390 sni_name='supermessage')
3391 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3392
3393 @needs_sni
3394 def test_sni_callback_raising(self):
3395 # Raising fails the connection with a TLS handshake failure alert.
3396 server_context, other_context, client_context = self.sni_contexts()
3397
3398 def cb_raising(ssl_sock, server_name, initial_context):
3399 1/0
3400 server_context.set_servername_callback(cb_raising)
3401
3402 with self.assertRaises(ssl.SSLError) as cm, \
3403 support.captured_stderr() as stderr:
3404 stats = server_params_test(client_context, server_context,
3405 chatty=False,
3406 sni_name='supermessage')
3407 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3408 self.assertIn("ZeroDivisionError", stderr.getvalue())
3409
3410 @needs_sni
3411 def test_sni_callback_wrong_return_type(self):
3412 # Returning the wrong return type terminates the TLS connection
3413 # with an internal error alert.
3414 server_context, other_context, client_context = self.sni_contexts()
3415
3416 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3417 return "foo"
3418 server_context.set_servername_callback(cb_wrong_return_type)
3419
3420 with self.assertRaises(ssl.SSLError) as cm, \
3421 support.captured_stderr() as stderr:
3422 stats = server_params_test(client_context, server_context,
3423 chatty=False,
3424 sni_name='supermessage')
3425 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3426 self.assertIn("TypeError", stderr.getvalue())
3427
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003428 def test_shared_ciphers(self):
Benjamin Petersonaacd5242015-01-07 11:42:38 -06003429 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson15042922015-01-07 22:12:43 -06003430 server_context.load_cert_chain(SIGNED_CERTFILE)
3431 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3432 client_context.verify_mode = ssl.CERT_REQUIRED
3433 client_context.load_verify_locations(SIGNING_CA)
Christian Heimes598894f2016-09-05 23:19:05 +02003434 if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
3435 client_context.set_ciphers("AES128:AES256")
3436 server_context.set_ciphers("AES256")
3437 alg1 = "AES256"
3438 alg2 = "AES-256"
3439 else:
3440 client_context.set_ciphers("AES:3DES")
3441 server_context.set_ciphers("3DES")
3442 alg1 = "3DES"
3443 alg2 = "DES-CBC3"
3444
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003445 stats = server_params_test(client_context, server_context)
3446 ciphers = stats['server_shared_ciphers'][0]
3447 self.assertGreater(len(ciphers), 0)
3448 for name, tls_version, bits in ciphers:
Christian Heimes598894f2016-09-05 23:19:05 +02003449 if not alg1 in name.split("-") and alg2 not in name:
3450 self.fail(name)
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003451
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003452 def test_read_write_after_close_raises_valuerror(self):
3453 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3454 context.verify_mode = ssl.CERT_REQUIRED
3455 context.load_verify_locations(CERTFILE)
3456 context.load_cert_chain(CERTFILE)
3457 server = ThreadedEchoServer(context=context, chatty=False)
3458
3459 with server:
3460 s = context.wrap_socket(socket.socket())
3461 s.connect((HOST, server.port))
3462 s.close()
3463
3464 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02003465 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003466
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02003467 def test_sendfile(self):
3468 TEST_DATA = b"x" * 512
3469 with open(support.TESTFN, 'wb') as f:
3470 f.write(TEST_DATA)
3471 self.addCleanup(support.unlink, support.TESTFN)
3472 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3473 context.verify_mode = ssl.CERT_REQUIRED
3474 context.load_verify_locations(CERTFILE)
3475 context.load_cert_chain(CERTFILE)
3476 server = ThreadedEchoServer(context=context, chatty=False)
3477 with server:
3478 with context.wrap_socket(socket.socket()) as s:
3479 s.connect((HOST, server.port))
3480 with open(support.TESTFN, 'rb') as file:
3481 s.sendfile(file)
3482 self.assertEqual(s.recv(1024), TEST_DATA)
3483
Christian Heimes99a65702016-09-10 23:44:53 +02003484 def test_session(self):
3485 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3486 server_context.load_cert_chain(SIGNED_CERTFILE)
3487 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3488 client_context.verify_mode = ssl.CERT_REQUIRED
3489 client_context.load_verify_locations(SIGNING_CA)
3490
Martin Panterb1321fb2016-10-10 00:38:21 +00003491 # first connection without session
Christian Heimes99a65702016-09-10 23:44:53 +02003492 stats = server_params_test(client_context, server_context)
3493 session = stats['session']
3494 self.assertTrue(session.id)
3495 self.assertGreater(session.time, 0)
3496 self.assertGreater(session.timeout, 0)
3497 self.assertTrue(session.has_ticket)
3498 if ssl.OPENSSL_VERSION_INFO > (1, 0, 1):
3499 self.assertGreater(session.ticket_lifetime_hint, 0)
3500 self.assertFalse(stats['session_reused'])
3501 sess_stat = server_context.session_stats()
3502 self.assertEqual(sess_stat['accept'], 1)
3503 self.assertEqual(sess_stat['hits'], 0)
3504
3505 # reuse session
3506 stats = server_params_test(client_context, server_context, session=session)
3507 sess_stat = server_context.session_stats()
3508 self.assertEqual(sess_stat['accept'], 2)
3509 self.assertEqual(sess_stat['hits'], 1)
3510 self.assertTrue(stats['session_reused'])
3511 session2 = stats['session']
3512 self.assertEqual(session2.id, session.id)
3513 self.assertEqual(session2, session)
3514 self.assertIsNot(session2, session)
3515 self.assertGreaterEqual(session2.time, session.time)
3516 self.assertGreaterEqual(session2.timeout, session.timeout)
3517
3518 # another one without session
3519 stats = server_params_test(client_context, server_context)
3520 self.assertFalse(stats['session_reused'])
3521 session3 = stats['session']
3522 self.assertNotEqual(session3.id, session.id)
3523 self.assertNotEqual(session3, session)
3524 sess_stat = server_context.session_stats()
3525 self.assertEqual(sess_stat['accept'], 3)
3526 self.assertEqual(sess_stat['hits'], 1)
3527
3528 # reuse session again
3529 stats = server_params_test(client_context, server_context, session=session)
3530 self.assertTrue(stats['session_reused'])
3531 session4 = stats['session']
3532 self.assertEqual(session4.id, session.id)
3533 self.assertEqual(session4, session)
3534 self.assertGreaterEqual(session4.time, session.time)
3535 self.assertGreaterEqual(session4.timeout, session.timeout)
3536 sess_stat = server_context.session_stats()
3537 self.assertEqual(sess_stat['accept'], 4)
3538 self.assertEqual(sess_stat['hits'], 2)
3539
3540 def test_session_handling(self):
3541 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3542 context.verify_mode = ssl.CERT_REQUIRED
3543 context.load_verify_locations(CERTFILE)
3544 context.load_cert_chain(CERTFILE)
3545
3546 context2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3547 context2.verify_mode = ssl.CERT_REQUIRED
3548 context2.load_verify_locations(CERTFILE)
3549 context2.load_cert_chain(CERTFILE)
3550
3551 server = ThreadedEchoServer(context=context, chatty=False)
3552 with server:
3553 with context.wrap_socket(socket.socket()) as s:
3554 # session is None before handshake
3555 self.assertEqual(s.session, None)
3556 self.assertEqual(s.session_reused, None)
3557 s.connect((HOST, server.port))
3558 session = s.session
3559 self.assertTrue(session)
3560 with self.assertRaises(TypeError) as e:
3561 s.session = object
3562 self.assertEqual(str(e.exception), 'Value is not a SSLSession.')
3563
3564 with context.wrap_socket(socket.socket()) as s:
3565 s.connect((HOST, server.port))
3566 # cannot set session after handshake
3567 with self.assertRaises(ValueError) as e:
3568 s.session = session
3569 self.assertEqual(str(e.exception),
3570 'Cannot set session after handshake.')
3571
3572 with context.wrap_socket(socket.socket()) as s:
3573 # can set session before handshake and before the
3574 # connection was established
3575 s.session = session
3576 s.connect((HOST, server.port))
3577 self.assertEqual(s.session.id, session.id)
3578 self.assertEqual(s.session, session)
3579 self.assertEqual(s.session_reused, True)
3580
3581 with context2.wrap_socket(socket.socket()) as s:
3582 # cannot re-use session with a different SSLContext
3583 with self.assertRaises(ValueError) as e:
3584 s.session = session
3585 s.connect((HOST, server.port))
3586 self.assertEqual(str(e.exception),
3587 'Session refers to a different SSLContext.')
3588
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003589
Thomas Woutersed03b412007-08-28 21:37:11 +00003590def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00003591 if support.verbose:
Berker Peksag9e7990a2015-05-16 23:21:26 +03003592 import warnings
Antoine Pitrou15cee622010-08-04 16:45:21 +00003593 plats = {
3594 'Linux': platform.linux_distribution,
3595 'Mac': platform.mac_ver,
3596 'Windows': platform.win32_ver,
3597 }
Berker Peksag9e7990a2015-05-16 23:21:26 +03003598 with warnings.catch_warnings():
3599 warnings.filterwarnings(
3600 'ignore',
R David Murray44b548d2016-09-08 13:59:53 -04003601 r'dist\(\) and linux_distribution\(\) '
Berker Peksag9e7990a2015-05-16 23:21:26 +03003602 'functions are deprecated .*',
3603 PendingDeprecationWarning,
3604 )
3605 for name, func in plats.items():
3606 plat = func()
3607 if plat and plat[0]:
3608 plat = '%s %r' % (name, plat)
3609 break
3610 else:
3611 plat = repr(platform.platform())
Antoine Pitrou15cee622010-08-04 16:45:21 +00003612 print("test_ssl: testing with %r %r" %
3613 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3614 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00003615 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01003616 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3617 try:
3618 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3619 except AttributeError:
3620 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00003621
Antoine Pitrou152efa22010-05-16 18:19:27 +00003622 for filename in [
Martin Panter3840b2a2016-03-27 01:53:46 +00003623 CERTFILE, BYTES_CERTFILE,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003624 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003625 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003626 BADCERT, BADKEY, EMPTYCERT]:
3627 if not os.path.exists(filename):
3628 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003629
Martin Panter3840b2a2016-03-27 01:53:46 +00003630 tests = [
3631 ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
3632 SimpleBackgroundTests,
3633 ]
Thomas Woutersed03b412007-08-28 21:37:11 +00003634
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003635 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00003636 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003637
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003638 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003639 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01003640 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00003641 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003642
Antoine Pitrou480a1242010-04-28 21:37:09 +00003643 try:
3644 support.run_unittest(*tests)
3645 finally:
3646 if _have_threads:
3647 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00003648
3649if __name__ == "__main__":
3650 test_main()