blob: fdaf1c52046f1528638cad1242f3e816a72e1cfd [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")
1247 def test_load_default_certs_env_windows(self):
1248 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1249 ctx.load_default_certs()
1250 stats = ctx.cert_store_stats()
1251
1252 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1253 with support.EnvironmentVarGuard() as env:
1254 env["SSL_CERT_DIR"] = CAPATH
1255 env["SSL_CERT_FILE"] = CERTFILE
1256 ctx.load_default_certs()
1257 stats["x509"] += 1
1258 self.assertEqual(ctx.cert_store_stats(), stats)
1259
Christian Heimes358cfd42016-09-10 22:43:48 +02001260 def _assert_context_options(self, ctx):
1261 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1262 if OP_NO_COMPRESSION != 0:
1263 self.assertEqual(ctx.options & OP_NO_COMPRESSION,
1264 OP_NO_COMPRESSION)
1265 if OP_SINGLE_DH_USE != 0:
1266 self.assertEqual(ctx.options & OP_SINGLE_DH_USE,
1267 OP_SINGLE_DH_USE)
1268 if OP_SINGLE_ECDH_USE != 0:
1269 self.assertEqual(ctx.options & OP_SINGLE_ECDH_USE,
1270 OP_SINGLE_ECDH_USE)
1271 if OP_CIPHER_SERVER_PREFERENCE != 0:
1272 self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE,
1273 OP_CIPHER_SERVER_PREFERENCE)
1274
Christian Heimes4c05b472013-11-23 15:58:30 +01001275 def test_create_default_context(self):
1276 ctx = ssl.create_default_context()
Christian Heimes358cfd42016-09-10 22:43:48 +02001277
Donald Stufft6a2ba942014-03-23 19:05:28 -04001278 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001279 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001280 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001281 self._assert_context_options(ctx)
1282
Christian Heimes4c05b472013-11-23 15:58:30 +01001283
1284 with open(SIGNING_CA) as f:
1285 cadata = f.read()
1286 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1287 cadata=cadata)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001288 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001289 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes358cfd42016-09-10 22:43:48 +02001290 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001291
1292 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001293 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001294 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001295 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001296
Christian Heimes67986f92013-11-23 22:43:47 +01001297 def test__create_stdlib_context(self):
1298 ctx = ssl._create_stdlib_context()
1299 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1300 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001301 self.assertFalse(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001302 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001303
1304 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1305 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1306 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001307 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001308
1309 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001310 cert_reqs=ssl.CERT_REQUIRED,
1311 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001312 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1313 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001314 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001315 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001316
1317 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1318 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1319 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001320 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001321
Christian Heimes1aa9a752013-12-02 02:41:19 +01001322 def test_check_hostname(self):
1323 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1324 self.assertFalse(ctx.check_hostname)
1325
1326 # Requires CERT_REQUIRED or CERT_OPTIONAL
1327 with self.assertRaises(ValueError):
1328 ctx.check_hostname = True
1329 ctx.verify_mode = ssl.CERT_REQUIRED
1330 self.assertFalse(ctx.check_hostname)
1331 ctx.check_hostname = True
1332 self.assertTrue(ctx.check_hostname)
1333
1334 ctx.verify_mode = ssl.CERT_OPTIONAL
1335 ctx.check_hostname = True
1336 self.assertTrue(ctx.check_hostname)
1337
1338 # Cannot set CERT_NONE with check_hostname enabled
1339 with self.assertRaises(ValueError):
1340 ctx.verify_mode = ssl.CERT_NONE
1341 ctx.check_hostname = False
1342 self.assertFalse(ctx.check_hostname)
1343
Christian Heimes5fe668c2016-09-12 00:01:11 +02001344 def test_context_client_server(self):
1345 # PROTOCOL_TLS_CLIENT has sane defaults
1346 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
1347 self.assertTrue(ctx.check_hostname)
1348 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1349
1350 # PROTOCOL_TLS_SERVER has different but also sane defaults
1351 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
1352 self.assertFalse(ctx.check_hostname)
1353 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1354
Antoine Pitrou152efa22010-05-16 18:19:27 +00001355
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001356class SSLErrorTests(unittest.TestCase):
1357
1358 def test_str(self):
1359 # The str() of a SSLError doesn't include the errno
1360 e = ssl.SSLError(1, "foo")
1361 self.assertEqual(str(e), "foo")
1362 self.assertEqual(e.errno, 1)
1363 # Same for a subclass
1364 e = ssl.SSLZeroReturnError(1, "foo")
1365 self.assertEqual(str(e), "foo")
1366 self.assertEqual(e.errno, 1)
1367
1368 def test_lib_reason(self):
1369 # Test the library and reason attributes
1370 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1371 with self.assertRaises(ssl.SSLError) as cm:
1372 ctx.load_dh_params(CERTFILE)
1373 self.assertEqual(cm.exception.library, 'PEM')
1374 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1375 s = str(cm.exception)
1376 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1377
1378 def test_subclass(self):
1379 # Check that the appropriate SSLError subclass is raised
1380 # (this only tests one of them)
1381 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1382 with socket.socket() as s:
1383 s.bind(("127.0.0.1", 0))
Charles-François Natali6e204602014-07-23 19:28:13 +01001384 s.listen()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001385 c = socket.socket()
1386 c.connect(s.getsockname())
1387 c.setblocking(False)
1388 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001389 with self.assertRaises(ssl.SSLWantReadError) as cm:
1390 c.do_handshake()
1391 s = str(cm.exception)
1392 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1393 # For compatibility
1394 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1395
Nathaniel J. Smith59fdf0f2017-06-09 02:35:16 -07001396 def test_bad_idna_in_server_hostname(self):
1397 # Note: this test is testing some code that probably shouldn't exist
1398 # in the first place, so if it starts failing at some point because
1399 # you made the ssl module stop doing IDNA decoding then please feel
1400 # free to remove it. The test was mainly added because this case used
1401 # to cause memory corruption (see bpo-30594).
1402 ctx = ssl.create_default_context()
1403 with self.assertRaises(UnicodeError):
1404 ctx.wrap_bio(ssl.MemoryBIO(), ssl.MemoryBIO(),
1405 server_hostname="xn--.com")
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001406
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001407class MemoryBIOTests(unittest.TestCase):
1408
1409 def test_read_write(self):
1410 bio = ssl.MemoryBIO()
1411 bio.write(b'foo')
1412 self.assertEqual(bio.read(), b'foo')
1413 self.assertEqual(bio.read(), b'')
1414 bio.write(b'foo')
1415 bio.write(b'bar')
1416 self.assertEqual(bio.read(), b'foobar')
1417 self.assertEqual(bio.read(), b'')
1418 bio.write(b'baz')
1419 self.assertEqual(bio.read(2), b'ba')
1420 self.assertEqual(bio.read(1), b'z')
1421 self.assertEqual(bio.read(1), b'')
1422
1423 def test_eof(self):
1424 bio = ssl.MemoryBIO()
1425 self.assertFalse(bio.eof)
1426 self.assertEqual(bio.read(), b'')
1427 self.assertFalse(bio.eof)
1428 bio.write(b'foo')
1429 self.assertFalse(bio.eof)
1430 bio.write_eof()
1431 self.assertFalse(bio.eof)
1432 self.assertEqual(bio.read(2), b'fo')
1433 self.assertFalse(bio.eof)
1434 self.assertEqual(bio.read(1), b'o')
1435 self.assertTrue(bio.eof)
1436 self.assertEqual(bio.read(), b'')
1437 self.assertTrue(bio.eof)
1438
1439 def test_pending(self):
1440 bio = ssl.MemoryBIO()
1441 self.assertEqual(bio.pending, 0)
1442 bio.write(b'foo')
1443 self.assertEqual(bio.pending, 3)
1444 for i in range(3):
1445 bio.read(1)
1446 self.assertEqual(bio.pending, 3-i-1)
1447 for i in range(3):
1448 bio.write(b'x')
1449 self.assertEqual(bio.pending, i+1)
1450 bio.read()
1451 self.assertEqual(bio.pending, 0)
1452
1453 def test_buffer_types(self):
1454 bio = ssl.MemoryBIO()
1455 bio.write(b'foo')
1456 self.assertEqual(bio.read(), b'foo')
1457 bio.write(bytearray(b'bar'))
1458 self.assertEqual(bio.read(), b'bar')
1459 bio.write(memoryview(b'baz'))
1460 self.assertEqual(bio.read(), b'baz')
1461
1462 def test_error_types(self):
1463 bio = ssl.MemoryBIO()
1464 self.assertRaises(TypeError, bio.write, 'foo')
1465 self.assertRaises(TypeError, bio.write, None)
1466 self.assertRaises(TypeError, bio.write, True)
1467 self.assertRaises(TypeError, bio.write, 1)
1468
1469
Martin Panter3840b2a2016-03-27 01:53:46 +00001470@unittest.skipUnless(_have_threads, "Needs threading module")
1471class SimpleBackgroundTests(unittest.TestCase):
1472
1473 """Tests that connect to a simple server running in the background"""
1474
1475 def setUp(self):
1476 server = ThreadedEchoServer(SIGNED_CERTFILE)
1477 self.server_addr = (HOST, server.port)
1478 server.__enter__()
1479 self.addCleanup(server.__exit__, None, None, None)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001480
Antoine Pitrou480a1242010-04-28 21:37:09 +00001481 def test_connect(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001482 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001483 cert_reqs=ssl.CERT_NONE) as s:
1484 s.connect(self.server_addr)
1485 self.assertEqual({}, s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001486 self.assertFalse(s.server_side)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001487
Martin Panter3840b2a2016-03-27 01:53:46 +00001488 # this should succeed because we specify the root cert
Christian Heimesd0486372016-09-10 23:23:33 +02001489 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001490 cert_reqs=ssl.CERT_REQUIRED,
1491 ca_certs=SIGNING_CA) as s:
1492 s.connect(self.server_addr)
1493 self.assertTrue(s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001494 self.assertFalse(s.server_side)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001495
Martin Panter3840b2a2016-03-27 01:53:46 +00001496 def test_connect_fail(self):
1497 # This should fail because we have no verification certs. Connection
1498 # failure crashes ThreadedEchoServer, so run this in an independent
1499 # test method.
Christian Heimesd0486372016-09-10 23:23:33 +02001500 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001501 cert_reqs=ssl.CERT_REQUIRED)
1502 self.addCleanup(s.close)
1503 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1504 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001505
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001506 def test_connect_ex(self):
1507 # Issue #11326: check connect_ex() implementation
Christian Heimesd0486372016-09-10 23:23:33 +02001508 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001509 cert_reqs=ssl.CERT_REQUIRED,
1510 ca_certs=SIGNING_CA)
1511 self.addCleanup(s.close)
1512 self.assertEqual(0, s.connect_ex(self.server_addr))
1513 self.assertTrue(s.getpeercert())
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001514
1515 def test_non_blocking_connect_ex(self):
1516 # Issue #11326: non-blocking connect_ex() should allow handshake
1517 # to proceed after the socket gets ready.
Christian Heimesd0486372016-09-10 23:23:33 +02001518 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001519 cert_reqs=ssl.CERT_REQUIRED,
1520 ca_certs=SIGNING_CA,
1521 do_handshake_on_connect=False)
1522 self.addCleanup(s.close)
1523 s.setblocking(False)
1524 rc = s.connect_ex(self.server_addr)
1525 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1526 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
1527 # Wait for connect to finish
1528 select.select([], [s], [], 5.0)
1529 # Non-blocking handshake
1530 while True:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001531 try:
Martin Panter3840b2a2016-03-27 01:53:46 +00001532 s.do_handshake()
1533 break
1534 except ssl.SSLWantReadError:
1535 select.select([s], [], [], 5.0)
1536 except ssl.SSLWantWriteError:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001537 select.select([], [s], [], 5.0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001538 # SSL established
1539 self.assertTrue(s.getpeercert())
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001540
Antoine Pitrou152efa22010-05-16 18:19:27 +00001541 def test_connect_with_context(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001542 # Same as test_connect, but with a separately created context
1543 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1544 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1545 s.connect(self.server_addr)
1546 self.assertEqual({}, s.getpeercert())
1547 # Same with a server hostname
1548 with ctx.wrap_socket(socket.socket(socket.AF_INET),
1549 server_hostname="dummy") as s:
1550 s.connect(self.server_addr)
1551 ctx.verify_mode = ssl.CERT_REQUIRED
1552 # This should succeed because we specify the root cert
1553 ctx.load_verify_locations(SIGNING_CA)
1554 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1555 s.connect(self.server_addr)
1556 cert = s.getpeercert()
1557 self.assertTrue(cert)
1558
1559 def test_connect_with_context_fail(self):
1560 # This should fail because we have no verification certs. Connection
1561 # failure crashes ThreadedEchoServer, so run this in an independent
1562 # test method.
1563 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1564 ctx.verify_mode = ssl.CERT_REQUIRED
1565 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1566 self.addCleanup(s.close)
1567 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1568 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001569
1570 def test_connect_capath(self):
1571 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001572 # NOTE: the subject hashing algorithm has been changed between
1573 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1574 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001575 # filename) for this test to be portable across OpenSSL releases.
Martin Panter3840b2a2016-03-27 01:53:46 +00001576 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1577 ctx.verify_mode = ssl.CERT_REQUIRED
1578 ctx.load_verify_locations(capath=CAPATH)
1579 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1580 s.connect(self.server_addr)
1581 cert = s.getpeercert()
1582 self.assertTrue(cert)
1583 # Same with a bytes `capath` argument
1584 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1585 ctx.verify_mode = ssl.CERT_REQUIRED
1586 ctx.load_verify_locations(capath=BYTES_CAPATH)
1587 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1588 s.connect(self.server_addr)
1589 cert = s.getpeercert()
1590 self.assertTrue(cert)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001591
Christian Heimesefff7062013-11-21 03:35:02 +01001592 def test_connect_cadata(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001593 with open(SIGNING_CA) as f:
Christian Heimesefff7062013-11-21 03:35:02 +01001594 pem = f.read()
1595 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panter3840b2a2016-03-27 01:53:46 +00001596 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1597 ctx.verify_mode = ssl.CERT_REQUIRED
1598 ctx.load_verify_locations(cadata=pem)
1599 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1600 s.connect(self.server_addr)
1601 cert = s.getpeercert()
1602 self.assertTrue(cert)
Christian Heimesefff7062013-11-21 03:35:02 +01001603
Martin Panter3840b2a2016-03-27 01:53:46 +00001604 # same with DER
1605 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1606 ctx.verify_mode = ssl.CERT_REQUIRED
1607 ctx.load_verify_locations(cadata=der)
1608 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1609 s.connect(self.server_addr)
1610 cert = s.getpeercert()
1611 self.assertTrue(cert)
Christian Heimesefff7062013-11-21 03:35:02 +01001612
Antoine Pitroue3220242010-04-24 11:13:53 +00001613 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1614 def test_makefile_close(self):
1615 # Issue #5238: creating a file-like object with makefile() shouldn't
1616 # delay closing the underlying "real socket" (here tested with its
1617 # file descriptor, hence skipping the test under Windows).
Christian Heimesd0486372016-09-10 23:23:33 +02001618 ss = test_wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3840b2a2016-03-27 01:53:46 +00001619 ss.connect(self.server_addr)
1620 fd = ss.fileno()
1621 f = ss.makefile()
1622 f.close()
1623 # The fd is still open
1624 os.read(fd, 0)
1625 # Closing the SSL socket should close the fd too
1626 ss.close()
1627 gc.collect()
1628 with self.assertRaises(OSError) as e:
Antoine Pitroue3220242010-04-24 11:13:53 +00001629 os.read(fd, 0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001630 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001631
Antoine Pitrou480a1242010-04-28 21:37:09 +00001632 def test_non_blocking_handshake(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001633 s = socket.socket(socket.AF_INET)
1634 s.connect(self.server_addr)
1635 s.setblocking(False)
Christian Heimesd0486372016-09-10 23:23:33 +02001636 s = test_wrap_socket(s,
Martin Panter3840b2a2016-03-27 01:53:46 +00001637 cert_reqs=ssl.CERT_NONE,
1638 do_handshake_on_connect=False)
1639 self.addCleanup(s.close)
1640 count = 0
1641 while True:
1642 try:
1643 count += 1
1644 s.do_handshake()
1645 break
1646 except ssl.SSLWantReadError:
1647 select.select([s], [], [])
1648 except ssl.SSLWantWriteError:
1649 select.select([], [s], [])
1650 if support.verbose:
1651 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001652
Antoine Pitrou480a1242010-04-28 21:37:09 +00001653 def test_get_server_certificate(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001654 _test_get_server_certificate(self, *self.server_addr, cert=SIGNING_CA)
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001655
Martin Panter3840b2a2016-03-27 01:53:46 +00001656 def test_get_server_certificate_fail(self):
1657 # Connection failure crashes ThreadedEchoServer, so run this in an
1658 # independent test method
1659 _test_get_server_certificate_fail(self, *self.server_addr)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001660
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001661 def test_ciphers(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001662 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001663 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1664 s.connect(self.server_addr)
Christian Heimesd0486372016-09-10 23:23:33 +02001665 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001666 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1667 s.connect(self.server_addr)
1668 # Error checking can happen at instantiation or when connecting
1669 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
1670 with socket.socket(socket.AF_INET) as sock:
Christian Heimesd0486372016-09-10 23:23:33 +02001671 s = test_wrap_socket(sock,
Martin Panter3840b2a2016-03-27 01:53:46 +00001672 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1673 s.connect(self.server_addr)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001674
Christian Heimes9a5395a2013-06-17 15:44:12 +02001675 def test_get_ca_certs_capath(self):
1676 # capath certs are loaded on request
Martin Panter3840b2a2016-03-27 01:53:46 +00001677 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1678 ctx.verify_mode = ssl.CERT_REQUIRED
1679 ctx.load_verify_locations(capath=CAPATH)
1680 self.assertEqual(ctx.get_ca_certs(), [])
1681 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1682 s.connect(self.server_addr)
1683 cert = s.getpeercert()
1684 self.assertTrue(cert)
1685 self.assertEqual(len(ctx.get_ca_certs()), 1)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001686
Christian Heimes575596e2013-12-15 21:49:17 +01001687 @needs_sni
Christian Heimes8e7f3942013-12-05 07:41:08 +01001688 def test_context_setget(self):
1689 # Check that the context of a connected socket can be replaced.
Martin Panter3840b2a2016-03-27 01:53:46 +00001690 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1691 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1692 s = socket.socket(socket.AF_INET)
1693 with ctx1.wrap_socket(s) as ss:
1694 ss.connect(self.server_addr)
1695 self.assertIs(ss.context, ctx1)
1696 self.assertIs(ss._sslobj.context, ctx1)
1697 ss.context = ctx2
1698 self.assertIs(ss.context, ctx2)
1699 self.assertIs(ss._sslobj.context, ctx2)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001700
1701 def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs):
1702 # A simple IO loop. Call func(*args) depending on the error we get
1703 # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs.
1704 timeout = kwargs.get('timeout', 10)
1705 count = 0
1706 while True:
1707 errno = None
1708 count += 1
1709 try:
1710 ret = func(*args)
1711 except ssl.SSLError as e:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001712 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
Martin Panter40b97ec2016-01-14 13:05:46 +00001713 ssl.SSL_ERROR_WANT_WRITE):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001714 raise
1715 errno = e.errno
1716 # Get any data from the outgoing BIO irrespective of any error, and
1717 # send it to the socket.
1718 buf = outgoing.read()
1719 sock.sendall(buf)
1720 # If there's no error, we're done. For WANT_READ, we need to get
1721 # data from the socket and put it in the incoming BIO.
1722 if errno is None:
1723 break
1724 elif errno == ssl.SSL_ERROR_WANT_READ:
1725 buf = sock.recv(32768)
1726 if buf:
1727 incoming.write(buf)
1728 else:
1729 incoming.write_eof()
1730 if support.verbose:
1731 sys.stdout.write("Needed %d calls to complete %s().\n"
1732 % (count, func.__name__))
1733 return ret
1734
Martin Panter3840b2a2016-03-27 01:53:46 +00001735 def test_bio_handshake(self):
1736 sock = socket.socket(socket.AF_INET)
1737 self.addCleanup(sock.close)
1738 sock.connect(self.server_addr)
1739 incoming = ssl.MemoryBIO()
1740 outgoing = ssl.MemoryBIO()
1741 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1742 ctx.verify_mode = ssl.CERT_REQUIRED
1743 ctx.load_verify_locations(SIGNING_CA)
1744 ctx.check_hostname = True
1745 sslobj = ctx.wrap_bio(incoming, outgoing, False, 'localhost')
1746 self.assertIs(sslobj._sslobj.owner, sslobj)
1747 self.assertIsNone(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001748 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001749 self.assertRaises(ValueError, sslobj.getpeercert)
1750 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1751 self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
1752 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1753 self.assertTrue(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001754 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001755 self.assertTrue(sslobj.getpeercert())
1756 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1757 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
1758 try:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001759 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Martin Panter3840b2a2016-03-27 01:53:46 +00001760 except ssl.SSLSyscallError:
1761 # If the server shuts down the TCP connection without sending a
1762 # secure shutdown message, this is reported as SSL_ERROR_SYSCALL
1763 pass
1764 self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
1765
1766 def test_bio_read_write_data(self):
1767 sock = socket.socket(socket.AF_INET)
1768 self.addCleanup(sock.close)
1769 sock.connect(self.server_addr)
1770 incoming = ssl.MemoryBIO()
1771 outgoing = ssl.MemoryBIO()
1772 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1773 ctx.verify_mode = ssl.CERT_NONE
1774 sslobj = ctx.wrap_bio(incoming, outgoing, False)
1775 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1776 req = b'FOO\n'
1777 self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req)
1778 buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024)
1779 self.assertEqual(buf, b'foo\n')
1780 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001781
1782
Martin Panter3840b2a2016-03-27 01:53:46 +00001783class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001784
Martin Panter3840b2a2016-03-27 01:53:46 +00001785 def test_timeout_connect_ex(self):
1786 # Issue #12065: on a timeout, connect_ex() should return the original
1787 # errno (mimicking the behaviour of non-SSL sockets).
1788 with support.transient_internet(REMOTE_HOST):
Christian Heimesd0486372016-09-10 23:23:33 +02001789 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001790 cert_reqs=ssl.CERT_REQUIRED,
1791 do_handshake_on_connect=False)
1792 self.addCleanup(s.close)
1793 s.settimeout(0.0000001)
1794 rc = s.connect_ex((REMOTE_HOST, 443))
1795 if rc == 0:
1796 self.skipTest("REMOTE_HOST responded too quickly")
1797 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1798
1799 @unittest.skipUnless(support.IPV6_ENABLED, 'Needs IPv6')
1800 def test_get_server_certificate_ipv6(self):
1801 with support.transient_internet('ipv6.google.com'):
1802 _test_get_server_certificate(self, 'ipv6.google.com', 443)
1803 _test_get_server_certificate_fail(self, 'ipv6.google.com', 443)
1804
1805 def test_algorithms(self):
1806 # Issue #8484: all algorithms should be available when verifying a
1807 # certificate.
1808 # SHA256 was added in OpenSSL 0.9.8
1809 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1810 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
1811 # sha256.tbs-internet.com needs SNI to use the correct certificate
1812 if not ssl.HAS_SNI:
1813 self.skipTest("SNI needed for this test")
1814 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1815 remote = ("sha256.tbs-internet.com", 443)
1816 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
1817 with support.transient_internet("sha256.tbs-internet.com"):
1818 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1819 ctx.verify_mode = ssl.CERT_REQUIRED
1820 ctx.load_verify_locations(sha256_cert)
1821 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1822 server_hostname="sha256.tbs-internet.com")
1823 try:
1824 s.connect(remote)
1825 if support.verbose:
1826 sys.stdout.write("\nCipher with %r is %r\n" %
1827 (remote, s.cipher()))
1828 sys.stdout.write("Certificate is:\n%s\n" %
1829 pprint.pformat(s.getpeercert()))
1830 finally:
1831 s.close()
1832
1833
1834def _test_get_server_certificate(test, host, port, cert=None):
1835 pem = ssl.get_server_certificate((host, port))
1836 if not pem:
1837 test.fail("No server certificate on %s:%s!" % (host, port))
1838
1839 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
1840 if not pem:
1841 test.fail("No server certificate on %s:%s!" % (host, port))
1842 if support.verbose:
1843 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
1844
1845def _test_get_server_certificate_fail(test, host, port):
1846 try:
1847 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
1848 except ssl.SSLError as x:
1849 #should fail
1850 if support.verbose:
1851 sys.stdout.write("%s\n" % x)
1852 else:
1853 test.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1854
1855
1856if _have_threads:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001857 from test.ssl_servers import make_https_server
1858
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001859 class ThreadedEchoServer(threading.Thread):
1860
1861 class ConnectionHandler(threading.Thread):
1862
1863 """A mildly complicated class, because we want it to work both
1864 with and without the SSL wrapper around the socket connection, so
1865 that we can test the STARTTLS functionality."""
1866
Bill Janssen6e027db2007-11-15 22:23:56 +00001867 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001868 self.server = server
1869 self.running = False
1870 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001871 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001872 self.sock.setblocking(1)
1873 self.sslconn = None
1874 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001875 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001876
Antoine Pitrou480a1242010-04-28 21:37:09 +00001877 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001878 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001879 self.sslconn = self.server.context.wrap_socket(
1880 self.sock, server_side=True)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001881 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1882 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001883 except (ssl.SSLError, ConnectionResetError) as e:
1884 # We treat ConnectionResetError as though it were an
1885 # SSLError - OpenSSL on Ubuntu abruptly closes the
1886 # connection when asked to use an unsupported protocol.
1887 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001888 # XXX Various errors can have happened here, for example
1889 # a mismatching protocol version, an invalid certificate,
1890 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001891 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001892 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001893 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001894 self.running = False
1895 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001896 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001897 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001898 else:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001899 self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
Antoine Pitroub5218772010-05-21 09:56:06 +00001900 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001901 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001902 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001903 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1904 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001905 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001906 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1907 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001908 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001909 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001910 sys.stdout.write(" server: selected protocol is now "
1911 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001912 return True
1913
1914 def read(self):
1915 if self.sslconn:
1916 return self.sslconn.read()
1917 else:
1918 return self.sock.recv(1024)
1919
1920 def write(self, bytes):
1921 if self.sslconn:
1922 return self.sslconn.write(bytes)
1923 else:
1924 return self.sock.send(bytes)
1925
1926 def close(self):
1927 if self.sslconn:
1928 self.sslconn.close()
1929 else:
1930 self.sock.close()
1931
Antoine Pitrou480a1242010-04-28 21:37:09 +00001932 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001933 self.running = True
1934 if not self.server.starttls_server:
1935 if not self.wrap_conn():
1936 return
1937 while self.running:
1938 try:
1939 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001940 stripped = msg.strip()
1941 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001942 # eof, so quit this handler
1943 self.running = False
Martin Panter3840b2a2016-03-27 01:53:46 +00001944 try:
1945 self.sock = self.sslconn.unwrap()
1946 except OSError:
1947 # Many tests shut the TCP connection down
1948 # without an SSL shutdown. This causes
1949 # unwrap() to raise OSError with errno=0!
1950 pass
1951 else:
1952 self.sslconn = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001953 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001954 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001955 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001956 sys.stdout.write(" server: client closed connection\n")
1957 self.close()
1958 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001959 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001960 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001961 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001962 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001963 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001964 if not self.wrap_conn():
1965 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001966 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001967 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001968 if support.verbose and self.server.connectionchatty:
1969 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001970 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001971 self.sock = self.sslconn.unwrap()
1972 self.sslconn = None
1973 if support.verbose and self.server.connectionchatty:
1974 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001975 elif stripped == b'CB tls-unique':
1976 if support.verbose and self.server.connectionchatty:
1977 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1978 data = self.sslconn.get_channel_binding("tls-unique")
1979 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001980 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001981 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001982 self.server.connectionchatty):
1983 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001984 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1985 % (msg, ctype, msg.lower(), ctype))
1986 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001987 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001988 if self.server.chatty:
1989 handle_error("Test server failure:\n")
1990 self.close()
1991 self.running = False
1992 # normally, we'd just stop here, but for the test
1993 # harness, we want to stop the server
1994 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001995
Antoine Pitroub5218772010-05-21 09:56:06 +00001996 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001997 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001998 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersoncca27322015-01-23 16:35:37 -05001999 npn_protocols=None, alpn_protocols=None,
2000 ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00002001 if context:
2002 self.context = context
2003 else:
2004 self.context = ssl.SSLContext(ssl_version
2005 if ssl_version is not None
2006 else ssl.PROTOCOL_TLSv1)
2007 self.context.verify_mode = (certreqs if certreqs is not None
2008 else ssl.CERT_NONE)
2009 if cacerts:
2010 self.context.load_verify_locations(cacerts)
2011 if certificate:
2012 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002013 if npn_protocols:
2014 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05002015 if alpn_protocols:
2016 self.context.set_alpn_protocols(alpn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00002017 if ciphers:
2018 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002019 self.chatty = chatty
2020 self.connectionchatty = connectionchatty
2021 self.starttls_server = starttls_server
2022 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002023 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002024 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002025 self.active = False
Benjamin Petersoncca27322015-01-23 16:35:37 -05002026 self.selected_npn_protocols = []
2027 self.selected_alpn_protocols = []
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002028 self.shared_ciphers = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002029 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002030 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002031 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002032
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002033 def __enter__(self):
2034 self.start(threading.Event())
2035 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002036 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002037
2038 def __exit__(self, *args):
2039 self.stop()
2040 self.join()
2041
Antoine Pitrou480a1242010-04-28 21:37:09 +00002042 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002043 self.flag = flag
2044 threading.Thread.start(self)
2045
Antoine Pitrou480a1242010-04-28 21:37:09 +00002046 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00002047 self.sock.settimeout(0.05)
Charles-François Natali6e204602014-07-23 19:28:13 +01002048 self.sock.listen()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002049 self.active = True
2050 if self.flag:
2051 # signal an event
2052 self.flag.set()
2053 while self.active:
2054 try:
2055 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002056 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002057 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00002058 + repr(connaddr) + '\n')
2059 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002060 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01002061 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002062 except socket.timeout:
2063 pass
2064 except KeyboardInterrupt:
2065 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00002066 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002067
Antoine Pitrou480a1242010-04-28 21:37:09 +00002068 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002069 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002070
Bill Janssen54cc54c2007-12-14 22:08:56 +00002071 class AsyncoreEchoServer(threading.Thread):
2072
2073 # this one's based on asyncore.dispatcher
2074
2075 class EchoServer (asyncore.dispatcher):
2076
Victor Stinner1dae7452017-05-02 13:12:02 +02002077 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002078
2079 def __init__(self, conn, certfile):
Christian Heimesd0486372016-09-10 23:23:33 +02002080 self.socket = test_wrap_socket(conn, server_side=True,
Bill Janssen54cc54c2007-12-14 22:08:56 +00002081 certfile=certfile,
2082 do_handshake_on_connect=False)
2083 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002084 self._ssl_accepting = True
2085 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002086
2087 def readable(self):
2088 if isinstance(self.socket, ssl.SSLSocket):
2089 while self.socket.pending() > 0:
2090 self.handle_read_event()
2091 return True
2092
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002093 def _do_ssl_handshake(self):
2094 try:
2095 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02002096 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
2097 return
2098 except ssl.SSLEOFError:
2099 return self.handle_close()
2100 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002101 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002102 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002103 if err.args[0] == errno.ECONNABORTED:
2104 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002105 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002106 self._ssl_accepting = False
2107
2108 def handle_read(self):
2109 if self._ssl_accepting:
2110 self._do_ssl_handshake()
2111 else:
2112 data = self.recv(1024)
2113 if support.verbose:
2114 sys.stdout.write(" server: read %s from client\n" % repr(data))
2115 if not data:
2116 self.close()
2117 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002118 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00002119
2120 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00002121 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002122 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002123 sys.stdout.write(" server: closed connection %s\n" % self.socket)
2124
2125 def handle_error(self):
2126 raise
2127
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002128 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002129 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002130 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2131 self.port = support.bind_port(sock, '')
2132 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00002133 self.listen(5)
2134
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00002135 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002136 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002137 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
2138 self.ConnectionHandler(sock_obj, self.certfile)
2139
2140 def handle_error(self):
2141 raise
2142
Trent Nelson78520002008-04-10 20:54:35 +00002143 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002144 self.flag = None
2145 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002146 self.server = self.EchoServer(certfile)
2147 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00002148 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002149 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00002150
2151 def __str__(self):
2152 return "<%s %s>" % (self.__class__.__name__, self.server)
2153
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002154 def __enter__(self):
2155 self.start(threading.Event())
2156 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002157 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002158
2159 def __exit__(self, *args):
2160 if support.verbose:
2161 sys.stdout.write(" cleanup: stopping server.\n")
2162 self.stop()
2163 if support.verbose:
2164 sys.stdout.write(" cleanup: joining server thread.\n")
2165 self.join()
2166 if support.verbose:
2167 sys.stdout.write(" cleanup: successfully joined.\n")
Victor Stinner1dae7452017-05-02 13:12:02 +02002168 # make sure that ConnectionHandler is removed from socket_map
2169 asyncore.close_all(ignore_all=True)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002170
Bill Janssen54cc54c2007-12-14 22:08:56 +00002171 def start (self, flag=None):
2172 self.flag = flag
2173 threading.Thread.start(self)
2174
Antoine Pitrou480a1242010-04-28 21:37:09 +00002175 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002176 self.active = True
2177 if self.flag:
2178 self.flag.set()
2179 while self.active:
2180 try:
2181 asyncore.loop(1)
2182 except:
2183 pass
2184
Antoine Pitrou480a1242010-04-28 21:37:09 +00002185 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002186 self.active = False
2187 self.server.close()
2188
Antoine Pitroub5218772010-05-21 09:56:06 +00002189 def server_params_test(client_context, server_context, indata=b"FOO\n",
Christian Heimes99a65702016-09-10 23:44:53 +02002190 chatty=True, connectionchatty=False, sni_name=None,
2191 session=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00002192 """
2193 Launch a server, connect a client to it and try various reads
2194 and writes.
2195 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002196 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00002197 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002198 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00002199 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002200 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002201 with client_context.wrap_socket(socket.socket(),
Christian Heimes99a65702016-09-10 23:44:53 +02002202 server_hostname=sni_name, session=session) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002203 s.connect((HOST, server.port))
2204 for arg in [indata, bytearray(indata), memoryview(indata)]:
2205 if connectionchatty:
2206 if support.verbose:
2207 sys.stdout.write(
2208 " client: sending %r...\n" % indata)
2209 s.write(arg)
2210 outdata = s.read()
2211 if connectionchatty:
2212 if support.verbose:
2213 sys.stdout.write(" client: read %r\n" % outdata)
2214 if outdata != indata.lower():
2215 raise AssertionError(
2216 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2217 % (outdata[:20], len(outdata),
2218 indata[:20].lower(), len(indata)))
2219 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00002220 if connectionchatty:
2221 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002222 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002223 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01002224 'compression': s.compression(),
2225 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002226 'peercert': s.getpeercert(),
Benjamin Petersoncca27322015-01-23 16:35:37 -05002227 'client_alpn_protocol': s.selected_alpn_protocol(),
Antoine Pitrou47e40422014-09-04 21:00:10 +02002228 'client_npn_protocol': s.selected_npn_protocol(),
2229 'version': s.version(),
Christian Heimes99a65702016-09-10 23:44:53 +02002230 'session_reused': s.session_reused,
2231 'session': s.session,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002232 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01002233 s.close()
Benjamin Petersoncca27322015-01-23 16:35:37 -05002234 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2235 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002236 stats['server_shared_ciphers'] = server.shared_ciphers
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002237 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00002238
Antoine Pitroub5218772010-05-21 09:56:06 +00002239 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2240 certsreqs=None, server_options=0, client_options=0):
Antoine Pitrou47e40422014-09-04 21:00:10 +02002241 """
2242 Try to SSL-connect using *client_protocol* to *server_protocol*.
2243 If *expect_success* is true, assert that the connection succeeds,
2244 if it's false, assert that the connection fails.
2245 Also, if *expect_success* is a string, assert that it is the protocol
2246 version actually used by the connection.
2247 """
Benjamin Peterson2a691a82008-03-31 01:51:45 +00002248 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002249 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00002250 certtype = {
2251 ssl.CERT_NONE: "CERT_NONE",
2252 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2253 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2254 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002255 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002256 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002257 sys.stdout.write(formatstr %
2258 (ssl.get_protocol_name(client_protocol),
2259 ssl.get_protocol_name(server_protocol),
2260 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00002261 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002262 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00002263 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002264 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002265
2266 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2267 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2268 # starting from OpenSSL 1.0.0 (see issue #8322).
2269 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2270 client_context.set_ciphers("ALL")
2271
Antoine Pitroub5218772010-05-21 09:56:06 +00002272 for ctx in (client_context, server_context):
2273 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00002274 ctx.load_cert_chain(CERTFILE)
2275 ctx.load_verify_locations(CERTFILE)
2276 try:
Antoine Pitrou47e40422014-09-04 21:00:10 +02002277 stats = server_params_test(client_context, server_context,
2278 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002279 # Protocol mismatch can result in either an SSLError, or a
2280 # "Connection reset by peer" error.
2281 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002282 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002283 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002284 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002285 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002286 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002287 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002288 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00002289 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002290 "Client protocol %s succeeded with server protocol %s!"
2291 % (ssl.get_protocol_name(client_protocol),
2292 ssl.get_protocol_name(server_protocol)))
Antoine Pitrou47e40422014-09-04 21:00:10 +02002293 elif (expect_success is not True
2294 and expect_success != stats['version']):
2295 raise AssertionError("version mismatch: expected %r, got %r"
2296 % (expect_success, stats['version']))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002297
2298
Bill Janssen6e027db2007-11-15 22:23:56 +00002299 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002300
Antoine Pitrou23df4832010-08-04 17:14:06 +00002301 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002302 def test_echo(self):
2303 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002304 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002305 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002306 for protocol in PROTOCOLS:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002307 if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
2308 continue
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01002309 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
2310 context = ssl.SSLContext(protocol)
2311 context.load_cert_chain(CERTFILE)
2312 server_params_test(context, context,
2313 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002314
Christian Heimes5fe668c2016-09-12 00:01:11 +02002315 client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
2316 client_context.load_verify_locations(SIGNING_CA)
2317 server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
2318 # server_context.load_verify_locations(SIGNING_CA)
2319 server_context.load_cert_chain(SIGNED_CERTFILE2)
2320
Christian Heimes9017ec12016-09-12 10:48:20 +02002321 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_SERVER):
Christian Heimes5fe668c2016-09-12 00:01:11 +02002322 server_params_test(client_context=client_context,
2323 server_context=server_context,
2324 chatty=True, connectionchatty=True,
2325 sni_name='fakehostname')
2326
Christian Heimes9017ec12016-09-12 10:48:20 +02002327 client_context.check_hostname = False
2328 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT):
2329 with self.assertRaises(ssl.SSLError) as e:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002330 server_params_test(client_context=server_context,
2331 server_context=client_context,
2332 chatty=True, connectionchatty=True,
2333 sni_name='fakehostname')
Christian Heimes9017ec12016-09-12 10:48:20 +02002334 self.assertIn('called a function you should not call',
2335 str(e.exception))
2336
2337 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER):
2338 with self.assertRaises(ssl.SSLError) as e:
2339 server_params_test(client_context=server_context,
2340 server_context=server_context,
2341 chatty=True, connectionchatty=True)
2342 self.assertIn('called a function you should not call',
2343 str(e.exception))
2344
2345 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_CLIENT):
2346 with self.assertRaises(ssl.SSLError) as e:
2347 server_params_test(client_context=server_context,
2348 server_context=client_context,
2349 chatty=True, connectionchatty=True)
2350 self.assertIn('called a function you should not call',
2351 str(e.exception))
2352
Christian Heimes5fe668c2016-09-12 00:01:11 +02002353
Antoine Pitrou480a1242010-04-28 21:37:09 +00002354 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002355 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002356 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002357 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2358 context.verify_mode = ssl.CERT_REQUIRED
2359 context.load_verify_locations(CERTFILE)
2360 context.load_cert_chain(CERTFILE)
2361 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002362 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02002363 s = context.wrap_socket(socket.socket(),
2364 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002365 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02002366 # getpeercert() raise ValueError while the handshake isn't
2367 # done.
2368 with self.assertRaises(ValueError):
2369 s.getpeercert()
2370 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002371 cert = s.getpeercert()
2372 self.assertTrue(cert, "Can't get peer certificate.")
2373 cipher = s.cipher()
2374 if support.verbose:
2375 sys.stdout.write(pprint.pformat(cert) + '\n')
2376 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2377 if 'subject' not in cert:
2378 self.fail("No subject field in certificate: %s." %
2379 pprint.pformat(cert))
2380 if ((('organizationName', 'Python Software Foundation'),)
2381 not in cert['subject']):
2382 self.fail(
2383 "Missing or invalid 'organizationName' field in certificate subject; "
2384 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00002385 self.assertIn('notBefore', cert)
2386 self.assertIn('notAfter', cert)
2387 before = ssl.cert_time_to_seconds(cert['notBefore'])
2388 after = ssl.cert_time_to_seconds(cert['notAfter'])
2389 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002390 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002391
Christian Heimes2427b502013-11-23 11:24:32 +01002392 @unittest.skipUnless(have_verify_flags(),
2393 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01002394 def test_crl_check(self):
2395 if support.verbose:
2396 sys.stdout.write("\n")
2397
2398 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2399 server_context.load_cert_chain(SIGNED_CERTFILE)
2400
2401 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2402 context.verify_mode = ssl.CERT_REQUIRED
2403 context.load_verify_locations(SIGNING_CA)
Benjamin Petersonc3d9c5c2015-03-04 23:18:48 -05002404 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2405 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +01002406
2407 # VERIFY_DEFAULT should pass
2408 server = ThreadedEchoServer(context=server_context, chatty=True)
2409 with server:
2410 with context.wrap_socket(socket.socket()) as s:
2411 s.connect((HOST, server.port))
2412 cert = s.getpeercert()
2413 self.assertTrue(cert, "Can't get peer certificate.")
2414
2415 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01002416 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01002417
2418 server = ThreadedEchoServer(context=server_context, chatty=True)
2419 with server:
2420 with context.wrap_socket(socket.socket()) as s:
2421 with self.assertRaisesRegex(ssl.SSLError,
2422 "certificate verify failed"):
2423 s.connect((HOST, server.port))
2424
2425 # now load a CRL file. The CRL file is signed by the CA.
2426 context.load_verify_locations(CRLFILE)
2427
2428 server = ThreadedEchoServer(context=server_context, chatty=True)
2429 with server:
2430 with context.wrap_socket(socket.socket()) as s:
2431 s.connect((HOST, server.port))
2432 cert = s.getpeercert()
2433 self.assertTrue(cert, "Can't get peer certificate.")
2434
Christian Heimes1aa9a752013-12-02 02:41:19 +01002435 def test_check_hostname(self):
2436 if support.verbose:
2437 sys.stdout.write("\n")
2438
2439 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2440 server_context.load_cert_chain(SIGNED_CERTFILE)
2441
2442 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2443 context.verify_mode = ssl.CERT_REQUIRED
2444 context.check_hostname = True
2445 context.load_verify_locations(SIGNING_CA)
2446
2447 # correct hostname should verify
2448 server = ThreadedEchoServer(context=server_context, chatty=True)
2449 with server:
2450 with context.wrap_socket(socket.socket(),
2451 server_hostname="localhost") as s:
2452 s.connect((HOST, server.port))
2453 cert = s.getpeercert()
2454 self.assertTrue(cert, "Can't get peer certificate.")
2455
2456 # incorrect hostname should raise an exception
2457 server = ThreadedEchoServer(context=server_context, chatty=True)
2458 with server:
2459 with context.wrap_socket(socket.socket(),
2460 server_hostname="invalid") as s:
2461 with self.assertRaisesRegex(ssl.CertificateError,
2462 "hostname 'invalid' doesn't match 'localhost'"):
2463 s.connect((HOST, server.port))
2464
2465 # missing server_hostname arg should cause an exception, too
2466 server = ThreadedEchoServer(context=server_context, chatty=True)
2467 with server:
2468 with socket.socket() as s:
2469 with self.assertRaisesRegex(ValueError,
2470 "check_hostname requires server_hostname"):
2471 context.wrap_socket(s)
2472
Martin Panter407b62f2016-01-30 03:41:43 +00002473 def test_wrong_cert(self):
Martin Panter3464ea22016-02-01 21:58:11 +00002474 """Connecting when the server rejects the client's certificate
2475
2476 Launch a server with CERT_REQUIRED, and check that trying to
2477 connect to it with a wrong client certificate fails.
2478 """
2479 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2480 "wrongcert.pem")
2481 server = ThreadedEchoServer(CERTFILE,
2482 certreqs=ssl.CERT_REQUIRED,
2483 cacerts=CERTFILE, chatty=False,
2484 connectionchatty=False)
2485 with server, \
2486 socket.socket() as sock, \
Christian Heimesd0486372016-09-10 23:23:33 +02002487 test_wrap_socket(sock,
Martin Panter3464ea22016-02-01 21:58:11 +00002488 certfile=certfile,
2489 ssl_version=ssl.PROTOCOL_TLSv1) as s:
2490 try:
2491 # Expect either an SSL error about the server rejecting
2492 # the connection, or a low-level connection reset (which
2493 # sometimes happens on Windows)
2494 s.connect((HOST, server.port))
2495 except ssl.SSLError as e:
2496 if support.verbose:
2497 sys.stdout.write("\nSSLError is %r\n" % e)
2498 except OSError as e:
2499 if e.errno != errno.ECONNRESET:
2500 raise
2501 if support.verbose:
2502 sys.stdout.write("\nsocket.error is %r\n" % e)
2503 else:
2504 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002505
Antoine Pitrou480a1242010-04-28 21:37:09 +00002506 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002507 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002508 in the client when attempting handshake.
2509 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002510 listener_ready = threading.Event()
2511 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002512
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002513 s = socket.socket()
2514 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002515
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002516 # `listener` runs in a thread. It sits in an accept() until
2517 # the main thread connects. Then it rudely closes the socket,
2518 # and sets Event `listener_gone` to let the main thread know
2519 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002520 def listener():
Charles-François Natali6e204602014-07-23 19:28:13 +01002521 s.listen()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002522 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002523 newsock, addr = s.accept()
2524 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002525 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002526 listener_gone.set()
2527
2528 def connector():
2529 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002530 with socket.socket() as c:
2531 c.connect((HOST, port))
2532 listener_gone.wait()
2533 try:
Christian Heimesd0486372016-09-10 23:23:33 +02002534 ssl_sock = test_wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002535 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002536 pass
2537 else:
2538 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002539
2540 t = threading.Thread(target=listener)
2541 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002542 try:
2543 connector()
2544 finally:
2545 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002546
Antoine Pitrou23df4832010-08-04 17:14:06 +00002547 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002548 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2549 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002550 def test_protocol_sslv2(self):
2551 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002552 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002553 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002554 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2555 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2556 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002557 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Victor Stinner648b8622014-12-12 12:23:59 +01002558 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2559 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002560 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002561 # SSLv23 client with specific SSL options
2562 if no_sslv2_implies_sslv3_hello():
2563 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2564 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2565 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002566 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002567 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002568 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002569 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002570
Antoine Pitrou23df4832010-08-04 17:14:06 +00002571 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002572 def test_protocol_sslv23(self):
2573 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002574 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002575 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002576 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2577 try:
2578 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002579 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002580 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2581 if support.verbose:
2582 sys.stdout.write(
2583 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2584 % str(x))
Benjamin Petersone32467c2014-12-05 21:59:35 -05002585 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002586 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002587 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002588 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002589
Benjamin Petersone32467c2014-12-05 21:59:35 -05002590 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002591 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002592 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002593 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002594
Benjamin Petersone32467c2014-12-05 21:59:35 -05002595 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002596 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002597 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002598 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002599
Antoine Pitroub5218772010-05-21 09:56:06 +00002600 # Server with specific SSL options
Benjamin Petersone32467c2014-12-05 21:59:35 -05002601 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2602 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002603 server_options=ssl.OP_NO_SSLv3)
2604 # Will choose TLSv1
2605 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2606 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2607 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2608 server_options=ssl.OP_NO_TLSv1)
2609
2610
Antoine Pitrou23df4832010-08-04 17:14:06 +00002611 @skip_if_broken_ubuntu_ssl
Benjamin Petersone32467c2014-12-05 21:59:35 -05002612 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2613 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002614 def test_protocol_sslv3(self):
2615 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002616 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002617 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002618 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2619 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2620 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002621 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2622 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002623 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2624 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002625 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002626 if no_sslv2_implies_sslv3_hello():
2627 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002628 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2629 False, client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002630
Antoine Pitrou23df4832010-08-04 17:14:06 +00002631 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002632 def test_protocol_tlsv1(self):
2633 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002634 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002635 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002636 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2637 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2638 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002639 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2640 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002641 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2642 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002643 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2644 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002645
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002646 @skip_if_broken_ubuntu_ssl
2647 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2648 "TLS version 1.1 not supported.")
2649 def test_protocol_tlsv1_1(self):
2650 """Connecting to a TLSv1.1 server with various client options.
2651 Testing against older TLS versions."""
2652 if support.verbose:
2653 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002654 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002655 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2656 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002657 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2658 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002659 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2660 client_options=ssl.OP_NO_TLSv1_1)
2661
Antoine Pitrou47e40422014-09-04 21:00:10 +02002662 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002663 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2664 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2665
2666
2667 @skip_if_broken_ubuntu_ssl
2668 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2669 "TLS version 1.2 not supported.")
2670 def test_protocol_tlsv1_2(self):
2671 """Connecting to a TLSv1.2 server with various client options.
2672 Testing against older TLS versions."""
2673 if support.verbose:
2674 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002675 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002676 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2677 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2678 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2679 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002680 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2681 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002682 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2683 client_options=ssl.OP_NO_TLSv1_2)
2684
Antoine Pitrou47e40422014-09-04 21:00:10 +02002685 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002686 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2687 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2688 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2689 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2690
Antoine Pitrou480a1242010-04-28 21:37:09 +00002691 def test_starttls(self):
2692 """Switching from clear text to encrypted and back again."""
2693 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 +00002694
Trent Nelson78520002008-04-10 20:54:35 +00002695 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002696 ssl_version=ssl.PROTOCOL_TLSv1,
2697 starttls_server=True,
2698 chatty=True,
2699 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002700 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002701 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002702 s = socket.socket()
2703 s.setblocking(1)
2704 s.connect((HOST, server.port))
2705 if support.verbose:
2706 sys.stdout.write("\n")
2707 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002708 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002709 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002710 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002711 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002712 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002713 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002714 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002715 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002716 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002717 msg = outdata.strip().lower()
2718 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2719 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002720 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002721 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002722 " client: read %r from server, starting TLS...\n"
2723 % msg)
Christian Heimesd0486372016-09-10 23:23:33 +02002724 conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002725 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002726 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2727 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002728 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002729 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002730 " client: read %r from server, ending TLS...\n"
2731 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002732 s = conn.unwrap()
2733 wrapped = False
2734 else:
2735 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002736 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002737 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002738 if support.verbose:
2739 sys.stdout.write(" client: closing connection.\n")
2740 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002741 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002742 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002743 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002744 if wrapped:
2745 conn.close()
2746 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002747 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002748
Antoine Pitrou480a1242010-04-28 21:37:09 +00002749 def test_socketserver(self):
Martin Panter463ef2b2016-09-22 09:37:56 +00002750 """Using socketserver to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002751 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002752 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002753 if support.verbose:
2754 sys.stdout.write('\n')
2755 with open(CERTFILE, 'rb') as f:
2756 d1 = f.read()
2757 d2 = ''
2758 # now fetch the same data from the HTTPS server
Benjamin Peterson4ffb0752014-11-03 14:29:33 -05002759 url = 'https://localhost:%d/%s' % (
2760 server.port, os.path.split(CERTFILE)[1])
2761 context = ssl.create_default_context(cafile=CERTFILE)
2762 f = urllib.request.urlopen(url, context=context)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002763 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002764 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002765 if dlen and (int(dlen) > 0):
2766 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002767 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002768 sys.stdout.write(
2769 " client: read %d bytes from remote server '%s'\n"
2770 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002771 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002772 f.close()
2773 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002774
Antoine Pitrou480a1242010-04-28 21:37:09 +00002775 def test_asyncore_server(self):
2776 """Check the example asyncore integration."""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002777 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002778 sys.stdout.write("\n")
2779
Antoine Pitrou480a1242010-04-28 21:37:09 +00002780 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002781 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002782 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002783 s = test_wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002784 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002785 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002786 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002787 " client: sending %r...\n" % indata)
2788 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002789 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002790 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002791 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002792 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002793 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002794 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2795 % (outdata[:20], len(outdata),
2796 indata[:20].lower(), len(indata)))
2797 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002798 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002799 sys.stdout.write(" client: closing connection.\n")
2800 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002801 if support.verbose:
2802 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002803
Antoine Pitrou480a1242010-04-28 21:37:09 +00002804 def test_recv_send(self):
2805 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002806 if support.verbose:
2807 sys.stdout.write("\n")
2808
2809 server = ThreadedEchoServer(CERTFILE,
2810 certreqs=ssl.CERT_NONE,
2811 ssl_version=ssl.PROTOCOL_TLSv1,
2812 cacerts=CERTFILE,
2813 chatty=True,
2814 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002815 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002816 s = test_wrap_socket(socket.socket(),
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002817 server_side=False,
2818 certfile=CERTFILE,
2819 ca_certs=CERTFILE,
2820 cert_reqs=ssl.CERT_NONE,
2821 ssl_version=ssl.PROTOCOL_TLSv1)
2822 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002823 # helper methods for standardising recv* method signatures
2824 def _recv_into():
2825 b = bytearray(b"\0"*100)
2826 count = s.recv_into(b)
2827 return b[:count]
2828
2829 def _recvfrom_into():
2830 b = bytearray(b"\0"*100)
2831 count, addr = s.recvfrom_into(b)
2832 return b[:count]
2833
Martin Panter519f9122016-04-03 02:12:54 +00002834 # (name, method, expect success?, *args, return value func)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002835 send_methods = [
Martin Panter519f9122016-04-03 02:12:54 +00002836 ('send', s.send, True, [], len),
2837 ('sendto', s.sendto, False, ["some.address"], len),
2838 ('sendall', s.sendall, True, [], lambda x: None),
Bill Janssen58afe4c2008-09-08 16:45:19 +00002839 ]
Martin Panter519f9122016-04-03 02:12:54 +00002840 # (name, method, whether to expect success, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002841 recv_methods = [
2842 ('recv', s.recv, True, []),
2843 ('recvfrom', s.recvfrom, False, ["some.address"]),
2844 ('recv_into', _recv_into, True, []),
2845 ('recvfrom_into', _recvfrom_into, False, []),
2846 ]
2847 data_prefix = "PREFIX_"
2848
Martin Panter519f9122016-04-03 02:12:54 +00002849 for (meth_name, send_meth, expect_success, args,
2850 ret_val_meth) in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002851 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002852 try:
Martin Panter519f9122016-04-03 02:12:54 +00002853 ret = send_meth(indata, *args)
2854 msg = "sending with {}".format(meth_name)
2855 self.assertEqual(ret, ret_val_meth(indata), msg=msg)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002856 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002857 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002858 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002859 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002860 "<<{outdata:r}>> ({nout:d}) received; "
2861 "expected <<{indata:r}>> ({nin:d})\n".format(
2862 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002863 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002864 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002865 )
2866 )
2867 except ValueError as e:
2868 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002869 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002870 "Failed to send with method <<{name:s}>>; "
2871 "expected to succeed.\n".format(name=meth_name)
2872 )
2873 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002874 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002875 "Method <<{name:s}>> failed with unexpected "
2876 "exception message: {exp:s}\n".format(
2877 name=meth_name, exp=e
2878 )
2879 )
2880
2881 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002882 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002883 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002884 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002885 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002886 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002887 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002888 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002889 "<<{outdata:r}>> ({nout:d}) received; "
2890 "expected <<{indata:r}>> ({nin:d})\n".format(
2891 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002892 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002893 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002894 )
2895 )
2896 except ValueError as e:
2897 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002898 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002899 "Failed to receive with method <<{name:s}>>; "
2900 "expected to succeed.\n".format(name=meth_name)
2901 )
2902 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002903 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002904 "Method <<{name:s}>> failed with unexpected "
2905 "exception message: {exp:s}\n".format(
2906 name=meth_name, exp=e
2907 )
2908 )
2909 # consume data
2910 s.read()
2911
Martin Panterf6b1d662016-03-28 00:22:09 +00002912 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panterbed7f1a2016-07-11 00:17:13 +00002913 data = b"data"
Martin Panter5503d472016-03-27 05:35:19 +00002914 s.send(data)
2915 buffer = bytearray(len(data))
2916 self.assertEqual(s.read(-1, buffer), len(data))
2917 self.assertEqual(buffer, data)
2918
Nick Coghlan513886a2011-08-28 00:00:27 +10002919 # Make sure sendmsg et al are disallowed to avoid
2920 # inadvertent disclosure of data and/or corruption
2921 # of the encrypted data stream
2922 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2923 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2924 self.assertRaises(NotImplementedError,
2925 s.recvmsg_into, bytearray(100))
2926
Antoine Pitrou480a1242010-04-28 21:37:09 +00002927 s.write(b"over\n")
Martin Panter5503d472016-03-27 05:35:19 +00002928
2929 self.assertRaises(ValueError, s.recv, -1)
2930 self.assertRaises(ValueError, s.read, -1)
2931
Bill Janssen58afe4c2008-09-08 16:45:19 +00002932 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002933
Martin Panterbed7f1a2016-07-11 00:17:13 +00002934 def test_recv_zero(self):
2935 server = ThreadedEchoServer(CERTFILE)
2936 server.__enter__()
2937 self.addCleanup(server.__exit__, None, None)
2938 s = socket.create_connection((HOST, server.port))
2939 self.addCleanup(s.close)
Christian Heimesd0486372016-09-10 23:23:33 +02002940 s = test_wrap_socket(s, suppress_ragged_eofs=False)
Martin Panterbed7f1a2016-07-11 00:17:13 +00002941 self.addCleanup(s.close)
2942
2943 # recv/read(0) should return no data
2944 s.send(b"data")
2945 self.assertEqual(s.recv(0), b"")
2946 self.assertEqual(s.read(0), b"")
2947 self.assertEqual(s.read(), b"data")
2948
2949 # Should not block if the other end sends no data
2950 s.setblocking(False)
2951 self.assertEqual(s.recv(0), b"")
2952 self.assertEqual(s.recv_into(bytearray()), 0)
2953
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002954 def test_nonblocking_send(self):
2955 server = ThreadedEchoServer(CERTFILE,
2956 certreqs=ssl.CERT_NONE,
2957 ssl_version=ssl.PROTOCOL_TLSv1,
2958 cacerts=CERTFILE,
2959 chatty=True,
2960 connectionchatty=False)
2961 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002962 s = test_wrap_socket(socket.socket(),
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002963 server_side=False,
2964 certfile=CERTFILE,
2965 ca_certs=CERTFILE,
2966 cert_reqs=ssl.CERT_NONE,
2967 ssl_version=ssl.PROTOCOL_TLSv1)
2968 s.connect((HOST, server.port))
2969 s.setblocking(False)
2970
2971 # If we keep sending data, at some point the buffers
2972 # will be full and the call will block
2973 buf = bytearray(8192)
2974 def fill_buffer():
2975 while True:
2976 s.send(buf)
2977 self.assertRaises((ssl.SSLWantWriteError,
2978 ssl.SSLWantReadError), fill_buffer)
2979
2980 # Now read all the output and discard it
2981 s.setblocking(True)
2982 s.close()
2983
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002984 def test_handshake_timeout(self):
2985 # Issue #5103: SSL handshake must respect the socket timeout
2986 server = socket.socket(socket.AF_INET)
2987 host = "127.0.0.1"
2988 port = support.bind_port(server)
2989 started = threading.Event()
2990 finish = False
2991
2992 def serve():
Charles-François Natali6e204602014-07-23 19:28:13 +01002993 server.listen()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002994 started.set()
2995 conns = []
2996 while not finish:
2997 r, w, e = select.select([server], [], [], 0.1)
2998 if server in r:
2999 # Let the socket hang around rather than having
3000 # it closed by garbage collection.
3001 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00003002 for sock in conns:
3003 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003004
3005 t = threading.Thread(target=serve)
3006 t.start()
3007 started.wait()
3008
3009 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00003010 try:
3011 c = socket.socket(socket.AF_INET)
3012 c.settimeout(0.2)
3013 c.connect((host, port))
3014 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003015 self.assertRaisesRegex(socket.timeout, "timed out",
Christian Heimesd0486372016-09-10 23:23:33 +02003016 test_wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00003017 finally:
3018 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003019 try:
3020 c = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +02003021 c = test_wrap_socket(c)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003022 c.settimeout(0.2)
3023 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003024 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00003025 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003026 finally:
3027 c.close()
3028 finally:
3029 finish = True
3030 t.join()
3031 server.close()
3032
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003033 def test_server_accept(self):
3034 # Issue #16357: accept() on a SSLSocket created through
3035 # SSLContext.wrap_socket().
3036 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3037 context.verify_mode = ssl.CERT_REQUIRED
3038 context.load_verify_locations(CERTFILE)
3039 context.load_cert_chain(CERTFILE)
3040 server = socket.socket(socket.AF_INET)
3041 host = "127.0.0.1"
3042 port = support.bind_port(server)
3043 server = context.wrap_socket(server, server_side=True)
Christian Heimesa5d07652016-09-24 10:48:05 +02003044 self.assertTrue(server.server_side)
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003045
3046 evt = threading.Event()
3047 remote = None
3048 peer = None
3049 def serve():
3050 nonlocal remote, peer
Charles-François Natali6e204602014-07-23 19:28:13 +01003051 server.listen()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003052 # Block on the accept and wait on the connection to close.
3053 evt.set()
3054 remote, peer = server.accept()
3055 remote.recv(1)
3056
3057 t = threading.Thread(target=serve)
3058 t.start()
3059 # Client wait until server setup and perform a connect.
3060 evt.wait()
3061 client = context.wrap_socket(socket.socket())
3062 client.connect((host, port))
3063 client_addr = client.getsockname()
3064 client.close()
3065 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003066 remote.close()
3067 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003068 # Sanity checks.
3069 self.assertIsInstance(remote, ssl.SSLSocket)
3070 self.assertEqual(peer, client_addr)
3071
Antoine Pitrou242db722013-05-01 20:52:07 +02003072 def test_getpeercert_enotconn(self):
3073 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3074 with context.wrap_socket(socket.socket()) as sock:
3075 with self.assertRaises(OSError) as cm:
3076 sock.getpeercert()
3077 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3078
3079 def test_do_handshake_enotconn(self):
3080 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3081 with context.wrap_socket(socket.socket()) as sock:
3082 with self.assertRaises(OSError) as cm:
3083 sock.do_handshake()
3084 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3085
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003086 def test_default_ciphers(self):
3087 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3088 try:
3089 # Force a set of weak ciphers on our client context
3090 context.set_ciphers("DES")
3091 except ssl.SSLError:
3092 self.skipTest("no DES cipher available")
3093 with ThreadedEchoServer(CERTFILE,
3094 ssl_version=ssl.PROTOCOL_SSLv23,
3095 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003096 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02003097 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003098 s.connect((HOST, server.port))
3099 self.assertIn("no shared cipher", str(server.conn_errors[0]))
3100
Antoine Pitrou47e40422014-09-04 21:00:10 +02003101 def test_version_basic(self):
3102 """
3103 Basic tests for SSLSocket.version().
3104 More tests are done in the test_protocol_*() methods.
3105 """
3106 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3107 with ThreadedEchoServer(CERTFILE,
3108 ssl_version=ssl.PROTOCOL_TLSv1,
3109 chatty=False) as server:
3110 with context.wrap_socket(socket.socket()) as s:
3111 self.assertIs(s.version(), None)
3112 s.connect((HOST, server.port))
Christian Heimes598894f2016-09-05 23:19:05 +02003113 self.assertEqual(s.version(), 'TLSv1')
Antoine Pitrou47e40422014-09-04 21:00:10 +02003114 self.assertIs(s.version(), None)
3115
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003116 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
3117 def test_default_ecdh_curve(self):
3118 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
3119 # should be enabled by default on SSL contexts.
3120 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3121 context.load_cert_chain(CERTFILE)
Antoine Pitrouc0430612014-04-16 18:33:39 +02003122 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
3123 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
3124 # our default cipher list should prefer ECDH-based ciphers
3125 # automatically.
3126 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
3127 context.set_ciphers("ECCdraft:ECDH")
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003128 with ThreadedEchoServer(context=context) as server:
3129 with context.wrap_socket(socket.socket()) as s:
3130 s.connect((HOST, server.port))
3131 self.assertIn("ECDH", s.cipher()[0])
3132
Antoine Pitroud6494802011-07-21 01:11:30 +02003133 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
3134 "'tls-unique' channel binding not available")
3135 def test_tls_unique_channel_binding(self):
3136 """Test tls-unique channel binding."""
3137 if support.verbose:
3138 sys.stdout.write("\n")
3139
3140 server = ThreadedEchoServer(CERTFILE,
3141 certreqs=ssl.CERT_NONE,
3142 ssl_version=ssl.PROTOCOL_TLSv1,
3143 cacerts=CERTFILE,
3144 chatty=True,
3145 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003146 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02003147 s = test_wrap_socket(socket.socket(),
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003148 server_side=False,
3149 certfile=CERTFILE,
3150 ca_certs=CERTFILE,
3151 cert_reqs=ssl.CERT_NONE,
3152 ssl_version=ssl.PROTOCOL_TLSv1)
3153 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02003154 # get the data
3155 cb_data = s.get_channel_binding("tls-unique")
3156 if support.verbose:
3157 sys.stdout.write(" got channel binding data: {0!r}\n"
3158 .format(cb_data))
3159
3160 # check if it is sane
3161 self.assertIsNotNone(cb_data)
3162 self.assertEqual(len(cb_data), 12) # True for TLSv1
3163
3164 # and compare with the peers version
3165 s.write(b"CB tls-unique\n")
3166 peer_data_repr = s.read().strip()
3167 self.assertEqual(peer_data_repr,
3168 repr(cb_data).encode("us-ascii"))
3169 s.close()
3170
3171 # now, again
Christian Heimesd0486372016-09-10 23:23:33 +02003172 s = test_wrap_socket(socket.socket(),
Antoine Pitroud6494802011-07-21 01:11:30 +02003173 server_side=False,
3174 certfile=CERTFILE,
3175 ca_certs=CERTFILE,
3176 cert_reqs=ssl.CERT_NONE,
3177 ssl_version=ssl.PROTOCOL_TLSv1)
3178 s.connect((HOST, server.port))
3179 new_cb_data = s.get_channel_binding("tls-unique")
3180 if support.verbose:
3181 sys.stdout.write(" got another channel binding data: {0!r}\n"
3182 .format(new_cb_data))
3183 # is it really unique
3184 self.assertNotEqual(cb_data, new_cb_data)
3185 self.assertIsNotNone(cb_data)
3186 self.assertEqual(len(cb_data), 12) # True for TLSv1
3187 s.write(b"CB tls-unique\n")
3188 peer_data_repr = s.read().strip()
3189 self.assertEqual(peer_data_repr,
3190 repr(new_cb_data).encode("us-ascii"))
3191 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00003192
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003193 def test_compression(self):
3194 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3195 context.load_cert_chain(CERTFILE)
3196 stats = server_params_test(context, context,
3197 chatty=True, connectionchatty=True)
3198 if support.verbose:
3199 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
3200 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
3201
3202 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
3203 "ssl.OP_NO_COMPRESSION needed for this test")
3204 def test_compression_disabled(self):
3205 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3206 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01003207 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003208 stats = server_params_test(context, context,
3209 chatty=True, connectionchatty=True)
3210 self.assertIs(stats['compression'], None)
3211
Antoine Pitrou0e576f12011-12-22 10:03:38 +01003212 def test_dh_params(self):
3213 # Check we can get a connection with ephemeral Diffie-Hellman
3214 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3215 context.load_cert_chain(CERTFILE)
3216 context.load_dh_params(DHFILE)
3217 context.set_ciphers("kEDH")
3218 stats = server_params_test(context, context,
3219 chatty=True, connectionchatty=True)
3220 cipher = stats["cipher"][0]
3221 parts = cipher.split("-")
3222 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
3223 self.fail("Non-DH cipher: " + cipher[0])
3224
Benjamin Petersoncca27322015-01-23 16:35:37 -05003225 def test_selected_alpn_protocol(self):
3226 # selected_alpn_protocol() is None unless ALPN is used.
3227 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3228 context.load_cert_chain(CERTFILE)
3229 stats = server_params_test(context, context,
3230 chatty=True, connectionchatty=True)
3231 self.assertIs(stats['client_alpn_protocol'], None)
3232
3233 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
3234 def test_selected_alpn_protocol_if_server_uses_alpn(self):
3235 # selected_alpn_protocol() is None unless ALPN is used by the client.
3236 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3237 client_context.load_verify_locations(CERTFILE)
3238 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3239 server_context.load_cert_chain(CERTFILE)
3240 server_context.set_alpn_protocols(['foo', 'bar'])
3241 stats = server_params_test(client_context, server_context,
3242 chatty=True, connectionchatty=True)
3243 self.assertIs(stats['client_alpn_protocol'], None)
3244
3245 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
3246 def test_alpn_protocols(self):
3247 server_protocols = ['foo', 'bar', 'milkshake']
3248 protocol_tests = [
3249 (['foo', 'bar'], 'foo'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003250 (['bar', 'foo'], 'foo'),
Benjamin Petersoncca27322015-01-23 16:35:37 -05003251 (['milkshake'], 'milkshake'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003252 (['http/3.0', 'http/4.0'], None)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003253 ]
3254 for client_protocols, expected in protocol_tests:
Christian Heimes598894f2016-09-05 23:19:05 +02003255 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003256 server_context.load_cert_chain(CERTFILE)
3257 server_context.set_alpn_protocols(server_protocols)
Christian Heimes598894f2016-09-05 23:19:05 +02003258 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003259 client_context.load_cert_chain(CERTFILE)
3260 client_context.set_alpn_protocols(client_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003261
Christian Heimes598894f2016-09-05 23:19:05 +02003262 try:
3263 stats = server_params_test(client_context,
3264 server_context,
3265 chatty=True,
3266 connectionchatty=True)
3267 except ssl.SSLError as e:
3268 stats = e
3269
3270 if expected is None and IS_OPENSSL_1_1:
3271 # OpenSSL 1.1.0 raises handshake error
3272 self.assertIsInstance(stats, ssl.SSLError)
3273 else:
3274 msg = "failed trying %s (s) and %s (c).\n" \
3275 "was expecting %s, but got %%s from the %%s" \
3276 % (str(server_protocols), str(client_protocols),
3277 str(expected))
3278 client_result = stats['client_alpn_protocol']
3279 self.assertEqual(client_result, expected,
3280 msg % (client_result, "client"))
3281 server_result = stats['server_alpn_protocols'][-1] \
3282 if len(stats['server_alpn_protocols']) else 'nothing'
3283 self.assertEqual(server_result, expected,
3284 msg % (server_result, "server"))
Benjamin Petersoncca27322015-01-23 16:35:37 -05003285
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01003286 def test_selected_npn_protocol(self):
3287 # selected_npn_protocol() is None unless NPN is used
3288 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3289 context.load_cert_chain(CERTFILE)
3290 stats = server_params_test(context, context,
3291 chatty=True, connectionchatty=True)
3292 self.assertIs(stats['client_npn_protocol'], None)
3293
3294 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
3295 def test_npn_protocols(self):
3296 server_protocols = ['http/1.1', 'spdy/2']
3297 protocol_tests = [
3298 (['http/1.1', 'spdy/2'], 'http/1.1'),
3299 (['spdy/2', 'http/1.1'], 'http/1.1'),
3300 (['spdy/2', 'test'], 'spdy/2'),
3301 (['abc', 'def'], 'abc')
3302 ]
3303 for client_protocols, expected in protocol_tests:
3304 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3305 server_context.load_cert_chain(CERTFILE)
3306 server_context.set_npn_protocols(server_protocols)
3307 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3308 client_context.load_cert_chain(CERTFILE)
3309 client_context.set_npn_protocols(client_protocols)
3310 stats = server_params_test(client_context, server_context,
3311 chatty=True, connectionchatty=True)
3312
3313 msg = "failed trying %s (s) and %s (c).\n" \
3314 "was expecting %s, but got %%s from the %%s" \
3315 % (str(server_protocols), str(client_protocols),
3316 str(expected))
3317 client_result = stats['client_npn_protocol']
3318 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3319 server_result = stats['server_npn_protocols'][-1] \
3320 if len(stats['server_npn_protocols']) else 'nothing'
3321 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3322
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003323 def sni_contexts(self):
3324 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3325 server_context.load_cert_chain(SIGNED_CERTFILE)
3326 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3327 other_context.load_cert_chain(SIGNED_CERTFILE2)
3328 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3329 client_context.verify_mode = ssl.CERT_REQUIRED
3330 client_context.load_verify_locations(SIGNING_CA)
3331 return server_context, other_context, client_context
3332
3333 def check_common_name(self, stats, name):
3334 cert = stats['peercert']
3335 self.assertIn((('commonName', name),), cert['subject'])
3336
3337 @needs_sni
3338 def test_sni_callback(self):
3339 calls = []
3340 server_context, other_context, client_context = self.sni_contexts()
3341
3342 def servername_cb(ssl_sock, server_name, initial_context):
3343 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003344 if server_name is not None:
3345 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003346 server_context.set_servername_callback(servername_cb)
3347
3348 stats = server_params_test(client_context, server_context,
3349 chatty=True,
3350 sni_name='supermessage')
3351 # The hostname was fetched properly, and the certificate was
3352 # changed for the connection.
3353 self.assertEqual(calls, [("supermessage", server_context)])
3354 # CERTFILE4 was selected
3355 self.check_common_name(stats, 'fakehostname')
3356
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003357 calls = []
3358 # The callback is called with server_name=None
3359 stats = server_params_test(client_context, server_context,
3360 chatty=True,
3361 sni_name=None)
3362 self.assertEqual(calls, [(None, server_context)])
3363 self.check_common_name(stats, 'localhost')
3364
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003365 # Check disabling the callback
3366 calls = []
3367 server_context.set_servername_callback(None)
3368
3369 stats = server_params_test(client_context, server_context,
3370 chatty=True,
3371 sni_name='notfunny')
3372 # Certificate didn't change
3373 self.check_common_name(stats, 'localhost')
3374 self.assertEqual(calls, [])
3375
3376 @needs_sni
3377 def test_sni_callback_alert(self):
3378 # Returning a TLS alert is reflected to the connecting client
3379 server_context, other_context, client_context = self.sni_contexts()
3380
3381 def cb_returning_alert(ssl_sock, server_name, initial_context):
3382 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3383 server_context.set_servername_callback(cb_returning_alert)
3384
3385 with self.assertRaises(ssl.SSLError) as cm:
3386 stats = server_params_test(client_context, server_context,
3387 chatty=False,
3388 sni_name='supermessage')
3389 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3390
3391 @needs_sni
3392 def test_sni_callback_raising(self):
3393 # Raising fails the connection with a TLS handshake failure alert.
3394 server_context, other_context, client_context = self.sni_contexts()
3395
3396 def cb_raising(ssl_sock, server_name, initial_context):
3397 1/0
3398 server_context.set_servername_callback(cb_raising)
3399
3400 with self.assertRaises(ssl.SSLError) as cm, \
3401 support.captured_stderr() as stderr:
3402 stats = server_params_test(client_context, server_context,
3403 chatty=False,
3404 sni_name='supermessage')
3405 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3406 self.assertIn("ZeroDivisionError", stderr.getvalue())
3407
3408 @needs_sni
3409 def test_sni_callback_wrong_return_type(self):
3410 # Returning the wrong return type terminates the TLS connection
3411 # with an internal error alert.
3412 server_context, other_context, client_context = self.sni_contexts()
3413
3414 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3415 return "foo"
3416 server_context.set_servername_callback(cb_wrong_return_type)
3417
3418 with self.assertRaises(ssl.SSLError) as cm, \
3419 support.captured_stderr() as stderr:
3420 stats = server_params_test(client_context, server_context,
3421 chatty=False,
3422 sni_name='supermessage')
3423 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3424 self.assertIn("TypeError", stderr.getvalue())
3425
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003426 def test_shared_ciphers(self):
Benjamin Petersonaacd5242015-01-07 11:42:38 -06003427 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson15042922015-01-07 22:12:43 -06003428 server_context.load_cert_chain(SIGNED_CERTFILE)
3429 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3430 client_context.verify_mode = ssl.CERT_REQUIRED
3431 client_context.load_verify_locations(SIGNING_CA)
Christian Heimes598894f2016-09-05 23:19:05 +02003432 if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
3433 client_context.set_ciphers("AES128:AES256")
3434 server_context.set_ciphers("AES256")
3435 alg1 = "AES256"
3436 alg2 = "AES-256"
3437 else:
3438 client_context.set_ciphers("AES:3DES")
3439 server_context.set_ciphers("3DES")
3440 alg1 = "3DES"
3441 alg2 = "DES-CBC3"
3442
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003443 stats = server_params_test(client_context, server_context)
3444 ciphers = stats['server_shared_ciphers'][0]
3445 self.assertGreater(len(ciphers), 0)
3446 for name, tls_version, bits in ciphers:
Christian Heimes598894f2016-09-05 23:19:05 +02003447 if not alg1 in name.split("-") and alg2 not in name:
3448 self.fail(name)
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003449
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003450 def test_read_write_after_close_raises_valuerror(self):
3451 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3452 context.verify_mode = ssl.CERT_REQUIRED
3453 context.load_verify_locations(CERTFILE)
3454 context.load_cert_chain(CERTFILE)
3455 server = ThreadedEchoServer(context=context, chatty=False)
3456
3457 with server:
3458 s = context.wrap_socket(socket.socket())
3459 s.connect((HOST, server.port))
3460 s.close()
3461
3462 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02003463 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003464
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02003465 def test_sendfile(self):
3466 TEST_DATA = b"x" * 512
3467 with open(support.TESTFN, 'wb') as f:
3468 f.write(TEST_DATA)
3469 self.addCleanup(support.unlink, support.TESTFN)
3470 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3471 context.verify_mode = ssl.CERT_REQUIRED
3472 context.load_verify_locations(CERTFILE)
3473 context.load_cert_chain(CERTFILE)
3474 server = ThreadedEchoServer(context=context, chatty=False)
3475 with server:
3476 with context.wrap_socket(socket.socket()) as s:
3477 s.connect((HOST, server.port))
3478 with open(support.TESTFN, 'rb') as file:
3479 s.sendfile(file)
3480 self.assertEqual(s.recv(1024), TEST_DATA)
3481
Christian Heimes99a65702016-09-10 23:44:53 +02003482 def test_session(self):
3483 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3484 server_context.load_cert_chain(SIGNED_CERTFILE)
3485 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3486 client_context.verify_mode = ssl.CERT_REQUIRED
3487 client_context.load_verify_locations(SIGNING_CA)
3488
Martin Panterb1321fb2016-10-10 00:38:21 +00003489 # first connection without session
Christian Heimes99a65702016-09-10 23:44:53 +02003490 stats = server_params_test(client_context, server_context)
3491 session = stats['session']
3492 self.assertTrue(session.id)
3493 self.assertGreater(session.time, 0)
3494 self.assertGreater(session.timeout, 0)
3495 self.assertTrue(session.has_ticket)
3496 if ssl.OPENSSL_VERSION_INFO > (1, 0, 1):
3497 self.assertGreater(session.ticket_lifetime_hint, 0)
3498 self.assertFalse(stats['session_reused'])
3499 sess_stat = server_context.session_stats()
3500 self.assertEqual(sess_stat['accept'], 1)
3501 self.assertEqual(sess_stat['hits'], 0)
3502
3503 # reuse session
3504 stats = server_params_test(client_context, server_context, session=session)
3505 sess_stat = server_context.session_stats()
3506 self.assertEqual(sess_stat['accept'], 2)
3507 self.assertEqual(sess_stat['hits'], 1)
3508 self.assertTrue(stats['session_reused'])
3509 session2 = stats['session']
3510 self.assertEqual(session2.id, session.id)
3511 self.assertEqual(session2, session)
3512 self.assertIsNot(session2, session)
3513 self.assertGreaterEqual(session2.time, session.time)
3514 self.assertGreaterEqual(session2.timeout, session.timeout)
3515
3516 # another one without session
3517 stats = server_params_test(client_context, server_context)
3518 self.assertFalse(stats['session_reused'])
3519 session3 = stats['session']
3520 self.assertNotEqual(session3.id, session.id)
3521 self.assertNotEqual(session3, session)
3522 sess_stat = server_context.session_stats()
3523 self.assertEqual(sess_stat['accept'], 3)
3524 self.assertEqual(sess_stat['hits'], 1)
3525
3526 # reuse session again
3527 stats = server_params_test(client_context, server_context, session=session)
3528 self.assertTrue(stats['session_reused'])
3529 session4 = stats['session']
3530 self.assertEqual(session4.id, session.id)
3531 self.assertEqual(session4, session)
3532 self.assertGreaterEqual(session4.time, session.time)
3533 self.assertGreaterEqual(session4.timeout, session.timeout)
3534 sess_stat = server_context.session_stats()
3535 self.assertEqual(sess_stat['accept'], 4)
3536 self.assertEqual(sess_stat['hits'], 2)
3537
3538 def test_session_handling(self):
3539 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3540 context.verify_mode = ssl.CERT_REQUIRED
3541 context.load_verify_locations(CERTFILE)
3542 context.load_cert_chain(CERTFILE)
3543
3544 context2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3545 context2.verify_mode = ssl.CERT_REQUIRED
3546 context2.load_verify_locations(CERTFILE)
3547 context2.load_cert_chain(CERTFILE)
3548
3549 server = ThreadedEchoServer(context=context, chatty=False)
3550 with server:
3551 with context.wrap_socket(socket.socket()) as s:
3552 # session is None before handshake
3553 self.assertEqual(s.session, None)
3554 self.assertEqual(s.session_reused, None)
3555 s.connect((HOST, server.port))
3556 session = s.session
3557 self.assertTrue(session)
3558 with self.assertRaises(TypeError) as e:
3559 s.session = object
3560 self.assertEqual(str(e.exception), 'Value is not a SSLSession.')
3561
3562 with context.wrap_socket(socket.socket()) as s:
3563 s.connect((HOST, server.port))
3564 # cannot set session after handshake
3565 with self.assertRaises(ValueError) as e:
3566 s.session = session
3567 self.assertEqual(str(e.exception),
3568 'Cannot set session after handshake.')
3569
3570 with context.wrap_socket(socket.socket()) as s:
3571 # can set session before handshake and before the
3572 # connection was established
3573 s.session = session
3574 s.connect((HOST, server.port))
3575 self.assertEqual(s.session.id, session.id)
3576 self.assertEqual(s.session, session)
3577 self.assertEqual(s.session_reused, True)
3578
3579 with context2.wrap_socket(socket.socket()) as s:
3580 # cannot re-use session with a different SSLContext
3581 with self.assertRaises(ValueError) as e:
3582 s.session = session
3583 s.connect((HOST, server.port))
3584 self.assertEqual(str(e.exception),
3585 'Session refers to a different SSLContext.')
3586
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003587
Thomas Woutersed03b412007-08-28 21:37:11 +00003588def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00003589 if support.verbose:
Berker Peksag9e7990a2015-05-16 23:21:26 +03003590 import warnings
Antoine Pitrou15cee622010-08-04 16:45:21 +00003591 plats = {
3592 'Linux': platform.linux_distribution,
3593 'Mac': platform.mac_ver,
3594 'Windows': platform.win32_ver,
3595 }
Berker Peksag9e7990a2015-05-16 23:21:26 +03003596 with warnings.catch_warnings():
3597 warnings.filterwarnings(
3598 'ignore',
R David Murray44b548d2016-09-08 13:59:53 -04003599 r'dist\(\) and linux_distribution\(\) '
Berker Peksag9e7990a2015-05-16 23:21:26 +03003600 'functions are deprecated .*',
3601 PendingDeprecationWarning,
3602 )
3603 for name, func in plats.items():
3604 plat = func()
3605 if plat and plat[0]:
3606 plat = '%s %r' % (name, plat)
3607 break
3608 else:
3609 plat = repr(platform.platform())
Antoine Pitrou15cee622010-08-04 16:45:21 +00003610 print("test_ssl: testing with %r %r" %
3611 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3612 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00003613 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01003614 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3615 try:
3616 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3617 except AttributeError:
3618 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00003619
Antoine Pitrou152efa22010-05-16 18:19:27 +00003620 for filename in [
Martin Panter3840b2a2016-03-27 01:53:46 +00003621 CERTFILE, BYTES_CERTFILE,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003622 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003623 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003624 BADCERT, BADKEY, EMPTYCERT]:
3625 if not os.path.exists(filename):
3626 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003627
Martin Panter3840b2a2016-03-27 01:53:46 +00003628 tests = [
3629 ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
3630 SimpleBackgroundTests,
3631 ]
Thomas Woutersed03b412007-08-28 21:37:11 +00003632
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003633 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00003634 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003635
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003636 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003637 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01003638 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00003639 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003640
Antoine Pitrou480a1242010-04-28 21:37:09 +00003641 try:
3642 support.run_unittest(*tests)
3643 finally:
3644 if _have_threads:
3645 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00003646
3647if __name__ == "__main__":
3648 test_main()