blob: d203cddbdfb5eefddab2870973ad12b093d90cd4 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Christian Heimes9424bb42013-06-17 15:32:57 +02009import datetime
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000010import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000011import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000012import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000013import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000014import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000015import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000016import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000017import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000018import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000019import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000020import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000021
Antoine Pitrou05d936d2010-10-13 11:38:36 +000022ssl = support.import_module("ssl")
23
Martin Panter3840b2a2016-03-27 01:53:46 +000024try:
25 import threading
26except ImportError:
27 _have_threads = False
28else:
29 _have_threads = True
30
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010031PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000032HOST = support.HOST
Christian Heimes598894f2016-09-05 23:19:05 +020033IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
34IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
35
Antoine Pitrou152efa22010-05-16 18:19:27 +000036
Christian Heimesefff7062013-11-21 03:35:02 +010037def data_file(*name):
38 return os.path.join(os.path.dirname(__file__), *name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000039
Antoine Pitrou81564092010-10-08 23:06:24 +000040# The custom key and certificate files used in test_ssl are generated
41# using Lib/test/make_ssl_certs.py.
42# Other certificates are simply fetched from the Internet servers they
43# are meant to authenticate.
44
Antoine Pitrou152efa22010-05-16 18:19:27 +000045CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000046BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000047ONLYCERT = data_file("ssl_cert.pem")
48ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000049BYTES_ONLYCERT = os.fsencode(ONLYCERT)
50BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +020051CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
52ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
53KEY_PASSWORD = "somepass"
Antoine Pitrou152efa22010-05-16 18:19:27 +000054CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000055BYTES_CAPATH = os.fsencode(CAPATH)
Christian Heimesefff7062013-11-21 03:35:02 +010056CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
57CAFILE_CACERT = data_file("capath", "5ed36f99.0")
58
Antoine Pitrou152efa22010-05-16 18:19:27 +000059
Christian Heimes22587792013-11-21 23:56:13 +010060# empty CRL
61CRLFILE = data_file("revocation.crl")
62
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010063# Two keys and certs signed by the same CA (for SNI tests)
64SIGNED_CERTFILE = data_file("keycert3.pem")
65SIGNED_CERTFILE2 = data_file("keycert4.pem")
Martin Panter3840b2a2016-03-27 01:53:46 +000066# Same certificate as pycacert.pem, but without extra text in file
67SIGNING_CA = data_file("capath", "ceff1710.0")
Christian Heimes1c03abd2016-09-06 23:25:35 +020068# cert with all kinds of subject alt names
69ALLSANFILE = data_file("allsans.pem")
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010070
Martin Panter3d81d932016-01-14 09:36:00 +000071REMOTE_HOST = "self-signed.pythontest.net"
Antoine Pitrou152efa22010-05-16 18:19:27 +000072
73EMPTYCERT = data_file("nullcert.pem")
74BADCERT = data_file("badcert.pem")
Martin Panter407b62f2016-01-30 03:41:43 +000075NONEXISTINGCERT = data_file("XXXnonexisting.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000076BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020077NOKIACERT = data_file("nokia.pem")
Christian Heimes824f7f32013-08-17 00:54:47 +020078NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000079
Benjamin Petersona7eaf562015-04-02 00:04:06 -040080DHFILE = data_file("dh1024.pem")
Antoine Pitrou0e576f12011-12-22 10:03:38 +010081BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000082
Christian Heimes358cfd42016-09-10 22:43:48 +020083# Not defined in all versions of OpenSSL
84OP_NO_COMPRESSION = getattr(ssl, "OP_NO_COMPRESSION", 0)
85OP_SINGLE_DH_USE = getattr(ssl, "OP_SINGLE_DH_USE", 0)
86OP_SINGLE_ECDH_USE = getattr(ssl, "OP_SINGLE_ECDH_USE", 0)
87OP_CIPHER_SERVER_PREFERENCE = getattr(ssl, "OP_CIPHER_SERVER_PREFERENCE", 0)
88
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010089
Thomas Woutersed03b412007-08-28 21:37:11 +000090def handle_error(prefix):
91 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000092 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000093 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000094
Antoine Pitroub5218772010-05-21 09:56:06 +000095def can_clear_options():
96 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020097 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000098
99def no_sslv2_implies_sslv3_hello():
100 # 0.9.7h or higher
101 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
102
Christian Heimes2427b502013-11-23 11:24:32 +0100103def have_verify_flags():
104 # 0.9.8 or higher
105 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
106
Antoine Pitrouc695c952014-04-28 20:57:36 +0200107def utc_offset(): #NOTE: ignore issues like #1647654
108 # local time = utc time + utc offset
109 if time.daylight and time.localtime().tm_isdst > 0:
110 return -time.altzone # seconds
111 return -time.timezone
112
Christian Heimes9424bb42013-06-17 15:32:57 +0200113def asn1time(cert_time):
114 # Some versions of OpenSSL ignore seconds, see #18207
115 # 0.9.8.i
116 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
117 fmt = "%b %d %H:%M:%S %Y GMT"
118 dt = datetime.datetime.strptime(cert_time, fmt)
119 dt = dt.replace(second=0)
120 cert_time = dt.strftime(fmt)
121 # %d adds leading zero but ASN1_TIME_print() uses leading space
122 if cert_time[4] == "0":
123 cert_time = cert_time[:4] + " " + cert_time[5:]
124
125 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +0000126
Antoine Pitrou23df4832010-08-04 17:14:06 +0000127# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
128def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +0200129 if hasattr(ssl, 'PROTOCOL_SSLv2'):
130 @functools.wraps(func)
131 def f(*args, **kwargs):
132 try:
133 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
134 except ssl.SSLError:
135 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
136 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
137 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
138 return func(*args, **kwargs)
139 return f
140 else:
141 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000142
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100143needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
144
Antoine Pitrou23df4832010-08-04 17:14:06 +0000145
Christian Heimesd0486372016-09-10 23:23:33 +0200146def test_wrap_socket(sock, ssl_version=ssl.PROTOCOL_TLS, *,
147 cert_reqs=ssl.CERT_NONE, ca_certs=None,
148 ciphers=None, certfile=None, keyfile=None,
149 **kwargs):
150 context = ssl.SSLContext(ssl_version)
151 if cert_reqs is not None:
152 context.verify_mode = cert_reqs
153 if ca_certs is not None:
154 context.load_verify_locations(ca_certs)
155 if certfile is not None or keyfile is not None:
156 context.load_cert_chain(certfile, keyfile)
157 if ciphers is not None:
158 context.set_ciphers(ciphers)
159 return context.wrap_socket(sock, **kwargs)
160
Antoine Pitrou152efa22010-05-16 18:19:27 +0000161class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000162
Antoine Pitrou480a1242010-04-28 21:37:09 +0000163 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000164 ssl.CERT_NONE
165 ssl.CERT_OPTIONAL
166 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100167 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100168 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100169 if ssl.HAS_ECDH:
170 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100171 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
172 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000173 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100174 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000175
Antoine Pitrou172f0252014-04-18 20:33:08 +0200176 def test_str_for_enums(self):
177 # Make sure that the PROTOCOL_* constants have enum-like string
178 # reprs.
Christian Heimes598894f2016-09-05 23:19:05 +0200179 proto = ssl.PROTOCOL_TLS
180 self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_TLS')
Antoine Pitrou172f0252014-04-18 20:33:08 +0200181 ctx = ssl.SSLContext(proto)
182 self.assertIs(ctx.protocol, proto)
183
Antoine Pitrou480a1242010-04-28 21:37:09 +0000184 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000185 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000186 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000187 sys.stdout.write("\n RAND_status is %d (%s)\n"
188 % (v, (v and "sufficient randomness") or
189 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200190
191 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
192 self.assertEqual(len(data), 16)
193 self.assertEqual(is_cryptographic, v == 1)
194 if v:
195 data = ssl.RAND_bytes(16)
196 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200197 else:
198 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200199
Victor Stinner1e81a392013-12-19 16:47:04 +0100200 # negative num is invalid
201 self.assertRaises(ValueError, ssl.RAND_bytes, -5)
202 self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5)
203
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100204 if hasattr(ssl, 'RAND_egd'):
205 self.assertRaises(TypeError, ssl.RAND_egd, 1)
206 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000207 ssl.RAND_add("this is a random string", 75.0)
Serhiy Storchaka8490f5a2015-03-20 09:00:36 +0200208 ssl.RAND_add(b"this is a random bytes object", 75.0)
209 ssl.RAND_add(bytearray(b"this is a random bytearray object"), 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000210
Christian Heimesf77b4b22013-08-21 13:26:05 +0200211 @unittest.skipUnless(os.name == 'posix', 'requires posix')
212 def test_random_fork(self):
213 status = ssl.RAND_status()
214 if not status:
215 self.fail("OpenSSL's PRNG has insufficient randomness")
216
217 rfd, wfd = os.pipe()
218 pid = os.fork()
219 if pid == 0:
220 try:
221 os.close(rfd)
222 child_random = ssl.RAND_pseudo_bytes(16)[0]
223 self.assertEqual(len(child_random), 16)
224 os.write(wfd, child_random)
225 os.close(wfd)
226 except BaseException:
227 os._exit(1)
228 else:
229 os._exit(0)
230 else:
231 os.close(wfd)
232 self.addCleanup(os.close, rfd)
233 _, status = os.waitpid(pid, 0)
234 self.assertEqual(status, 0)
235
236 child_random = os.read(rfd, 16)
237 self.assertEqual(len(child_random), 16)
238 parent_random = ssl.RAND_pseudo_bytes(16)[0]
239 self.assertEqual(len(parent_random), 16)
240
241 self.assertNotEqual(child_random, parent_random)
242
Antoine Pitrou480a1242010-04-28 21:37:09 +0000243 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000244 # note that this uses an 'unofficial' function in _ssl.c,
245 # provided solely for this test, to exercise the certificate
246 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000247 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000248 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000249 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200250 self.assertEqual(p['issuer'],
251 ((('countryName', 'XY'),),
252 (('localityName', 'Castle Anthrax'),),
253 (('organizationName', 'Python Software Foundation'),),
254 (('commonName', 'localhost'),))
255 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100256 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200257 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
258 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200259 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
260 self.assertEqual(p['subject'],
261 ((('countryName', 'XY'),),
262 (('localityName', 'Castle Anthrax'),),
263 (('organizationName', 'Python Software Foundation'),),
264 (('commonName', 'localhost'),))
265 )
266 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
267 # Issue #13034: the subjectAltName in some certificates
268 # (notably projects.developer.nokia.com:443) wasn't parsed
269 p = ssl._ssl._test_decode_cert(NOKIACERT)
270 if support.verbose:
271 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
272 self.assertEqual(p['subjectAltName'],
273 (('DNS', 'projects.developer.nokia.com'),
274 ('DNS', 'projects.forum.nokia.com'))
275 )
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100276 # extra OCSP and AIA fields
277 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
278 self.assertEqual(p['caIssuers'],
279 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
280 self.assertEqual(p['crlDistributionPoints'],
281 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Thomas Woutersed03b412007-08-28 21:37:11 +0000282
Christian Heimes824f7f32013-08-17 00:54:47 +0200283 def test_parse_cert_CVE_2013_4238(self):
284 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
285 if support.verbose:
286 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
287 subject = ((('countryName', 'US'),),
288 (('stateOrProvinceName', 'Oregon'),),
289 (('localityName', 'Beaverton'),),
290 (('organizationName', 'Python Software Foundation'),),
291 (('organizationalUnitName', 'Python Core Development'),),
292 (('commonName', 'null.python.org\x00example.org'),),
293 (('emailAddress', 'python-dev@python.org'),))
294 self.assertEqual(p['subject'], subject)
295 self.assertEqual(p['issuer'], subject)
Christian Heimes157c9832013-08-25 14:12:41 +0200296 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
297 san = (('DNS', 'altnull.python.org\x00example.com'),
298 ('email', 'null@python.org\x00user@example.org'),
299 ('URI', 'http://null.python.org\x00http://example.org'),
300 ('IP Address', '192.0.2.1'),
301 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
302 else:
303 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
304 san = (('DNS', 'altnull.python.org\x00example.com'),
305 ('email', 'null@python.org\x00user@example.org'),
306 ('URI', 'http://null.python.org\x00http://example.org'),
307 ('IP Address', '192.0.2.1'),
308 ('IP Address', '<invalid>'))
309
310 self.assertEqual(p['subjectAltName'], san)
Christian Heimes824f7f32013-08-17 00:54:47 +0200311
Christian Heimes1c03abd2016-09-06 23:25:35 +0200312 def test_parse_all_sans(self):
313 p = ssl._ssl._test_decode_cert(ALLSANFILE)
314 self.assertEqual(p['subjectAltName'],
315 (
316 ('DNS', 'allsans'),
317 ('othername', '<unsupported>'),
318 ('othername', '<unsupported>'),
319 ('email', 'user@example.org'),
320 ('DNS', 'www.example.org'),
321 ('DirName',
322 ((('countryName', 'XY'),),
323 (('localityName', 'Castle Anthrax'),),
324 (('organizationName', 'Python Software Foundation'),),
325 (('commonName', 'dirname example'),))),
326 ('URI', 'https://www.python.org/'),
327 ('IP Address', '127.0.0.1'),
328 ('IP Address', '0:0:0:0:0:0:0:1\n'),
329 ('Registered ID', '1.2.3.4.5')
330 )
331 )
332
Antoine Pitrou480a1242010-04-28 21:37:09 +0000333 def test_DER_to_PEM(self):
Martin Panter3d81d932016-01-14 09:36:00 +0000334 with open(CAFILE_CACERT, 'r') as f:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000335 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000336 d1 = ssl.PEM_cert_to_DER_cert(pem)
337 p2 = ssl.DER_cert_to_PEM_cert(d1)
338 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000339 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000340 if not p2.startswith(ssl.PEM_HEADER + '\n'):
341 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
342 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
343 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000344
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000345 def test_openssl_version(self):
346 n = ssl.OPENSSL_VERSION_NUMBER
347 t = ssl.OPENSSL_VERSION_INFO
348 s = ssl.OPENSSL_VERSION
349 self.assertIsInstance(n, int)
350 self.assertIsInstance(t, tuple)
351 self.assertIsInstance(s, str)
352 # Some sanity checks follow
353 # >= 0.9
354 self.assertGreaterEqual(n, 0x900000)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400355 # < 3.0
356 self.assertLess(n, 0x30000000)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000357 major, minor, fix, patch, status = t
358 self.assertGreaterEqual(major, 0)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400359 self.assertLess(major, 3)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000360 self.assertGreaterEqual(minor, 0)
361 self.assertLess(minor, 256)
362 self.assertGreaterEqual(fix, 0)
363 self.assertLess(fix, 256)
364 self.assertGreaterEqual(patch, 0)
Ned Deily05784a72015-02-05 17:20:13 +1100365 self.assertLessEqual(patch, 63)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000366 self.assertGreaterEqual(status, 0)
367 self.assertLessEqual(status, 15)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400368 # Version string as returned by {Open,Libre}SSL, the format might change
Christian Heimes598894f2016-09-05 23:19:05 +0200369 if IS_LIBRESSL:
370 self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
Victor Stinner789b8052015-01-06 11:51:06 +0100371 (s, t, hex(n)))
Antoine Pitroudfab9352014-07-21 18:35:01 -0400372 else:
373 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
Victor Stinner789b8052015-01-06 11:51:06 +0100374 (s, t, hex(n)))
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000375
Antoine Pitrou9d543662010-04-23 23:10:32 +0000376 @support.cpython_only
377 def test_refcycle(self):
378 # Issue #7943: an SSL object doesn't create reference cycles with
379 # itself.
380 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200381 ss = test_wrap_socket(s)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000382 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100383 with support.check_warnings(("", ResourceWarning)):
384 del ss
Victor Stinnere0b75b72016-03-21 17:26:04 +0100385 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000386
Antoine Pitroua468adc2010-09-14 14:43:44 +0000387 def test_wrapped_unconnected(self):
388 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200389 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000390 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200391 with test_wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100392 self.assertRaises(OSError, ss.recv, 1)
393 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
394 self.assertRaises(OSError, ss.recvfrom, 1)
395 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
396 self.assertRaises(OSError, ss.send, b'x')
397 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000398
Antoine Pitrou40f08742010-04-24 22:04:40 +0000399 def test_timeout(self):
400 # Issue #8524: when creating an SSL socket, the timeout of the
401 # original socket should be retained.
402 for timeout in (None, 0.0, 5.0):
403 s = socket.socket(socket.AF_INET)
404 s.settimeout(timeout)
Christian Heimesd0486372016-09-10 23:23:33 +0200405 with test_wrap_socket(s) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100406 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000407
Christian Heimesd0486372016-09-10 23:23:33 +0200408 def test_errors_sslwrap(self):
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000409 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000410 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000411 "certfile must be specified",
412 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000413 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000414 "certfile must be specified for server-side operations",
415 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000416 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000417 "certfile must be specified for server-side operations",
Christian Heimesd0486372016-09-10 23:23:33 +0200418 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100419 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
420 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
Christian Heimesd0486372016-09-10 23:23:33 +0200421 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200422 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000423 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000424 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000425 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200426 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000427 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000428 ssl.wrap_socket(sock,
429 certfile=CERTFILE, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000430 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200431 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000432 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000433 ssl.wrap_socket(sock,
434 certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000435 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000436
Martin Panter3464ea22016-02-01 21:58:11 +0000437 def bad_cert_test(self, certfile):
438 """Check that trying to use the given client certificate fails"""
439 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
440 certfile)
441 sock = socket.socket()
442 self.addCleanup(sock.close)
443 with self.assertRaises(ssl.SSLError):
Christian Heimesd0486372016-09-10 23:23:33 +0200444 test_wrap_socket(sock,
Martin Panter3464ea22016-02-01 21:58:11 +0000445 certfile=certfile,
446 ssl_version=ssl.PROTOCOL_TLSv1)
447
448 def test_empty_cert(self):
449 """Wrapping with an empty cert file"""
450 self.bad_cert_test("nullcert.pem")
451
452 def test_malformed_cert(self):
453 """Wrapping with a badly formatted certificate (syntax error)"""
454 self.bad_cert_test("badcert.pem")
455
456 def test_malformed_key(self):
457 """Wrapping with a badly formatted key (syntax error)"""
458 self.bad_cert_test("badkey.pem")
459
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000460 def test_match_hostname(self):
461 def ok(cert, hostname):
462 ssl.match_hostname(cert, hostname)
463 def fail(cert, hostname):
464 self.assertRaises(ssl.CertificateError,
465 ssl.match_hostname, cert, hostname)
466
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100467 # -- Hostname matching --
468
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000469 cert = {'subject': ((('commonName', 'example.com'),),)}
470 ok(cert, 'example.com')
471 ok(cert, 'ExAmple.cOm')
472 fail(cert, 'www.example.com')
473 fail(cert, '.example.com')
474 fail(cert, 'example.org')
475 fail(cert, 'exampleXcom')
476
477 cert = {'subject': ((('commonName', '*.a.com'),),)}
478 ok(cert, 'foo.a.com')
479 fail(cert, 'bar.foo.a.com')
480 fail(cert, 'a.com')
481 fail(cert, 'Xa.com')
482 fail(cert, '.a.com')
483
Georg Brandl72c98d32013-10-27 07:16:53 +0100484 # only match one left-most wildcard
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000485 cert = {'subject': ((('commonName', 'f*.com'),),)}
486 ok(cert, 'foo.com')
487 ok(cert, 'f.com')
488 fail(cert, 'bar.com')
489 fail(cert, 'foo.a.com')
490 fail(cert, 'bar.foo.com')
491
Christian Heimes824f7f32013-08-17 00:54:47 +0200492 # NULL bytes are bad, CVE-2013-4073
493 cert = {'subject': ((('commonName',
494 'null.python.org\x00example.org'),),)}
495 ok(cert, 'null.python.org\x00example.org') # or raise an error?
496 fail(cert, 'example.org')
497 fail(cert, 'null.python.org')
498
Georg Brandl72c98d32013-10-27 07:16:53 +0100499 # error cases with wildcards
500 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
501 fail(cert, 'bar.foo.a.com')
502 fail(cert, 'a.com')
503 fail(cert, 'Xa.com')
504 fail(cert, '.a.com')
505
506 cert = {'subject': ((('commonName', 'a.*.com'),),)}
507 fail(cert, 'a.foo.com')
508 fail(cert, 'a..com')
509 fail(cert, 'a.com')
510
511 # wildcard doesn't match IDNA prefix 'xn--'
512 idna = 'püthon.python.org'.encode("idna").decode("ascii")
513 cert = {'subject': ((('commonName', idna),),)}
514 ok(cert, idna)
515 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
516 fail(cert, idna)
517 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
518 fail(cert, idna)
519
520 # wildcard in first fragment and IDNA A-labels in sequent fragments
521 # are supported.
522 idna = 'www*.pythön.org'.encode("idna").decode("ascii")
523 cert = {'subject': ((('commonName', idna),),)}
524 ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
525 ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
526 fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
527 fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
528
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000529 # Slightly fake real-world example
530 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
531 'subject': ((('commonName', 'linuxfrz.org'),),),
532 'subjectAltName': (('DNS', 'linuxfr.org'),
533 ('DNS', 'linuxfr.com'),
534 ('othername', '<unsupported>'))}
535 ok(cert, 'linuxfr.org')
536 ok(cert, 'linuxfr.com')
537 # Not a "DNS" entry
538 fail(cert, '<unsupported>')
539 # When there is a subjectAltName, commonName isn't used
540 fail(cert, 'linuxfrz.org')
541
542 # A pristine real-world example
543 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
544 'subject': ((('countryName', 'US'),),
545 (('stateOrProvinceName', 'California'),),
546 (('localityName', 'Mountain View'),),
547 (('organizationName', 'Google Inc'),),
548 (('commonName', 'mail.google.com'),))}
549 ok(cert, 'mail.google.com')
550 fail(cert, 'gmail.com')
551 # Only commonName is considered
552 fail(cert, 'California')
553
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100554 # -- IPv4 matching --
555 cert = {'subject': ((('commonName', 'example.com'),),),
556 'subjectAltName': (('DNS', 'example.com'),
557 ('IP Address', '10.11.12.13'),
558 ('IP Address', '14.15.16.17'))}
559 ok(cert, '10.11.12.13')
560 ok(cert, '14.15.16.17')
561 fail(cert, '14.15.16.18')
562 fail(cert, 'example.net')
563
564 # -- IPv6 matching --
565 cert = {'subject': ((('commonName', 'example.com'),),),
566 'subjectAltName': (('DNS', 'example.com'),
567 ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'),
568 ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))}
569 ok(cert, '2001::cafe')
570 ok(cert, '2003::baba')
571 fail(cert, '2003::bebe')
572 fail(cert, 'example.net')
573
574 # -- Miscellaneous --
575
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000576 # Neither commonName nor subjectAltName
577 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
578 'subject': ((('countryName', 'US'),),
579 (('stateOrProvinceName', 'California'),),
580 (('localityName', 'Mountain View'),),
581 (('organizationName', 'Google Inc'),))}
582 fail(cert, 'mail.google.com')
583
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200584 # No DNS entry in subjectAltName but a commonName
585 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
586 'subject': ((('countryName', 'US'),),
587 (('stateOrProvinceName', 'California'),),
588 (('localityName', 'Mountain View'),),
589 (('commonName', 'mail.google.com'),)),
590 'subjectAltName': (('othername', 'blabla'), )}
591 ok(cert, 'mail.google.com')
592
593 # No DNS entry subjectAltName and no commonName
594 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
595 'subject': ((('countryName', 'US'),),
596 (('stateOrProvinceName', 'California'),),
597 (('localityName', 'Mountain View'),),
598 (('organizationName', 'Google Inc'),)),
599 'subjectAltName': (('othername', 'blabla'),)}
600 fail(cert, 'google.com')
601
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000602 # Empty cert / no cert
603 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
604 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
605
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200606 # Issue #17980: avoid denials of service by refusing more than one
607 # wildcard per fragment.
608 cert = {'subject': ((('commonName', 'a*b.com'),),)}
609 ok(cert, 'axxb.com')
610 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
Georg Brandl72c98d32013-10-27 07:16:53 +0100611 fail(cert, 'axxb.com')
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200612 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
613 with self.assertRaises(ssl.CertificateError) as cm:
614 ssl.match_hostname(cert, 'axxbxxc.com')
615 self.assertIn("too many wildcards", str(cm.exception))
616
Antoine Pitroud5323212010-10-22 18:19:07 +0000617 def test_server_side(self):
618 # server_hostname doesn't work for server sockets
619 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000620 with socket.socket() as sock:
621 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
622 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000623
Antoine Pitroud6494802011-07-21 01:11:30 +0200624 def test_unknown_channel_binding(self):
625 # should raise ValueError for unknown type
626 s = socket.socket(socket.AF_INET)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200627 s.bind(('127.0.0.1', 0))
628 s.listen()
629 c = socket.socket(socket.AF_INET)
630 c.connect(s.getsockname())
Christian Heimesd0486372016-09-10 23:23:33 +0200631 with test_wrap_socket(c, do_handshake_on_connect=False) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100632 with self.assertRaises(ValueError):
633 ss.get_channel_binding("unknown-type")
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200634 s.close()
Antoine Pitroud6494802011-07-21 01:11:30 +0200635
636 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
637 "'tls-unique' channel binding not available")
638 def test_tls_unique_channel_binding(self):
639 # unconnected should return None for known type
640 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200641 with test_wrap_socket(s) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100642 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200643 # the same for server-side
644 s = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +0200645 with test_wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100646 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200647
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600648 def test_dealloc_warn(self):
Christian Heimesd0486372016-09-10 23:23:33 +0200649 ss = test_wrap_socket(socket.socket(socket.AF_INET))
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600650 r = repr(ss)
651 with self.assertWarns(ResourceWarning) as cm:
652 ss = None
653 support.gc_collect()
654 self.assertIn(r, str(cm.warning.args[0]))
655
Christian Heimes6d7ad132013-06-09 18:02:55 +0200656 def test_get_default_verify_paths(self):
657 paths = ssl.get_default_verify_paths()
658 self.assertEqual(len(paths), 6)
659 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
660
661 with support.EnvironmentVarGuard() as env:
662 env["SSL_CERT_DIR"] = CAPATH
663 env["SSL_CERT_FILE"] = CERTFILE
664 paths = ssl.get_default_verify_paths()
665 self.assertEqual(paths.cafile, CERTFILE)
666 self.assertEqual(paths.capath, CAPATH)
667
Christian Heimes44109d72013-11-22 01:51:30 +0100668 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
669 def test_enum_certificates(self):
670 self.assertTrue(ssl.enum_certificates("CA"))
671 self.assertTrue(ssl.enum_certificates("ROOT"))
672
673 self.assertRaises(TypeError, ssl.enum_certificates)
674 self.assertRaises(WindowsError, ssl.enum_certificates, "")
675
Christian Heimesc2d65e12013-11-22 16:13:55 +0100676 trust_oids = set()
677 for storename in ("CA", "ROOT"):
678 store = ssl.enum_certificates(storename)
679 self.assertIsInstance(store, list)
680 for element in store:
681 self.assertIsInstance(element, tuple)
682 self.assertEqual(len(element), 3)
683 cert, enc, trust = element
684 self.assertIsInstance(cert, bytes)
685 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
686 self.assertIsInstance(trust, (set, bool))
687 if isinstance(trust, set):
688 trust_oids.update(trust)
Christian Heimes44109d72013-11-22 01:51:30 +0100689
690 serverAuth = "1.3.6.1.5.5.7.3.1"
Christian Heimesc2d65e12013-11-22 16:13:55 +0100691 self.assertIn(serverAuth, trust_oids)
Christian Heimes6d7ad132013-06-09 18:02:55 +0200692
Christian Heimes46bebee2013-06-09 19:03:31 +0200693 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Christian Heimes44109d72013-11-22 01:51:30 +0100694 def test_enum_crls(self):
695 self.assertTrue(ssl.enum_crls("CA"))
696 self.assertRaises(TypeError, ssl.enum_crls)
697 self.assertRaises(WindowsError, ssl.enum_crls, "")
Christian Heimes46bebee2013-06-09 19:03:31 +0200698
Christian Heimes44109d72013-11-22 01:51:30 +0100699 crls = ssl.enum_crls("CA")
700 self.assertIsInstance(crls, list)
701 for element in crls:
702 self.assertIsInstance(element, tuple)
703 self.assertEqual(len(element), 2)
704 self.assertIsInstance(element[0], bytes)
705 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
Christian Heimes46bebee2013-06-09 19:03:31 +0200706
Christian Heimes46bebee2013-06-09 19:03:31 +0200707
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100708 def test_asn1object(self):
709 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
710 '1.3.6.1.5.5.7.3.1')
711
712 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
713 self.assertEqual(val, expected)
714 self.assertEqual(val.nid, 129)
715 self.assertEqual(val.shortname, 'serverAuth')
716 self.assertEqual(val.longname, 'TLS Web Server Authentication')
717 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
718 self.assertIsInstance(val, ssl._ASN1Object)
719 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
720
721 val = ssl._ASN1Object.fromnid(129)
722 self.assertEqual(val, expected)
723 self.assertIsInstance(val, ssl._ASN1Object)
724 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100725 with self.assertRaisesRegex(ValueError, "unknown NID 100000"):
726 ssl._ASN1Object.fromnid(100000)
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100727 for i in range(1000):
728 try:
729 obj = ssl._ASN1Object.fromnid(i)
730 except ValueError:
731 pass
732 else:
733 self.assertIsInstance(obj.nid, int)
734 self.assertIsInstance(obj.shortname, str)
735 self.assertIsInstance(obj.longname, str)
736 self.assertIsInstance(obj.oid, (str, type(None)))
737
738 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
739 self.assertEqual(val, expected)
740 self.assertIsInstance(val, ssl._ASN1Object)
741 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
742 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
743 expected)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100744 with self.assertRaisesRegex(ValueError, "unknown object 'serverauth'"):
745 ssl._ASN1Object.fromname('serverauth')
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100746
Christian Heimes72d28502013-11-23 13:56:58 +0100747 def test_purpose_enum(self):
748 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
749 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
750 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
751 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
752 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
753 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
754 '1.3.6.1.5.5.7.3.1')
755
756 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
757 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
758 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
759 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
760 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
761 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
762 '1.3.6.1.5.5.7.3.2')
763
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100764 def test_unsupported_dtls(self):
765 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
766 self.addCleanup(s.close)
767 with self.assertRaises(NotImplementedError) as cx:
Christian Heimesd0486372016-09-10 23:23:33 +0200768 test_wrap_socket(s, cert_reqs=ssl.CERT_NONE)
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100769 self.assertEqual(str(cx.exception), "only stream sockets are supported")
770 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
771 with self.assertRaises(NotImplementedError) as cx:
772 ctx.wrap_socket(s)
773 self.assertEqual(str(cx.exception), "only stream sockets are supported")
774
Antoine Pitrouc695c952014-04-28 20:57:36 +0200775 def cert_time_ok(self, timestring, timestamp):
776 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
777
778 def cert_time_fail(self, timestring):
779 with self.assertRaises(ValueError):
780 ssl.cert_time_to_seconds(timestring)
781
782 @unittest.skipUnless(utc_offset(),
783 'local time needs to be different from UTC')
784 def test_cert_time_to_seconds_timezone(self):
785 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
786 # results if local timezone is not UTC
787 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
788 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
789
790 def test_cert_time_to_seconds(self):
791 timestring = "Jan 5 09:34:43 2018 GMT"
792 ts = 1515144883.0
793 self.cert_time_ok(timestring, ts)
794 # accept keyword parameter, assert its name
795 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
796 # accept both %e and %d (space or zero generated by strftime)
797 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
798 # case-insensitive
799 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
800 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
801 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
802 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
803 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
804 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
805 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
806 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
807
808 newyear_ts = 1230768000.0
809 # leap seconds
810 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
811 # same timestamp
812 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
813
814 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
815 # allow 60th second (even if it is not a leap second)
816 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
817 # allow 2nd leap second for compatibility with time.strptime()
818 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
819 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
820
821 # no special treatement for the special value:
822 # 99991231235959Z (rfc 5280)
823 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
824
825 @support.run_with_locale('LC_ALL', '')
826 def test_cert_time_to_seconds_locale(self):
827 # `cert_time_to_seconds()` should be locale independent
828
829 def local_february_name():
830 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
831
832 if local_february_name().lower() == 'feb':
833 self.skipTest("locale-specific month name needs to be "
834 "different from C locale")
835
836 # locale-independent
837 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
838 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
839
Martin Panter3840b2a2016-03-27 01:53:46 +0000840 def test_connect_ex_error(self):
841 server = socket.socket(socket.AF_INET)
842 self.addCleanup(server.close)
843 port = support.bind_port(server) # Reserve port but don't listen
Christian Heimesd0486372016-09-10 23:23:33 +0200844 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +0000845 cert_reqs=ssl.CERT_REQUIRED)
846 self.addCleanup(s.close)
847 rc = s.connect_ex((HOST, port))
848 # Issue #19919: Windows machines or VMs hosted on Windows
849 # machines sometimes return EWOULDBLOCK.
850 errors = (
851 errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
852 errno.EWOULDBLOCK,
853 )
854 self.assertIn(rc, errors)
855
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100856
Antoine Pitrou152efa22010-05-16 18:19:27 +0000857class ContextTests(unittest.TestCase):
858
Antoine Pitrou23df4832010-08-04 17:14:06 +0000859 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000860 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100861 for protocol in PROTOCOLS:
862 ssl.SSLContext(protocol)
Christian Heimes598894f2016-09-05 23:19:05 +0200863 ctx = ssl.SSLContext()
864 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000865 self.assertRaises(ValueError, ssl.SSLContext, -1)
866 self.assertRaises(ValueError, ssl.SSLContext, 42)
867
Antoine Pitrou23df4832010-08-04 17:14:06 +0000868 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000869 def test_protocol(self):
870 for proto in PROTOCOLS:
871 ctx = ssl.SSLContext(proto)
872 self.assertEqual(ctx.protocol, proto)
873
874 def test_ciphers(self):
875 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
876 ctx.set_ciphers("ALL")
877 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000878 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000879 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000880
Christian Heimes25bfcd52016-09-06 00:04:45 +0200881 @unittest.skipIf(ssl.OPENSSL_VERSION_INFO < (1, 0, 2, 0, 0), 'OpenSSL too old')
882 def test_get_ciphers(self):
883 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Christian Heimesea9b2dc2016-09-06 10:45:44 +0200884 ctx.set_ciphers('AESGCM')
Christian Heimes25bfcd52016-09-06 00:04:45 +0200885 names = set(d['name'] for d in ctx.get_ciphers())
Christian Heimes582282b2016-09-06 11:27:25 +0200886 self.assertIn('AES256-GCM-SHA384', names)
887 self.assertIn('AES128-GCM-SHA256', names)
Christian Heimes25bfcd52016-09-06 00:04:45 +0200888
Antoine Pitrou23df4832010-08-04 17:14:06 +0000889 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000890 def test_options(self):
891 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800892 # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
Christian Heimes598894f2016-09-05 23:19:05 +0200893 default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
Christian Heimes358cfd42016-09-10 22:43:48 +0200894 # SSLContext also enables these by default
895 default |= (OP_NO_COMPRESSION | OP_CIPHER_SERVER_PREFERENCE |
896 OP_SINGLE_DH_USE | OP_SINGLE_ECDH_USE)
Christian Heimes598894f2016-09-05 23:19:05 +0200897 self.assertEqual(default, ctx.options)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800898 ctx.options |= ssl.OP_NO_TLSv1
Christian Heimes598894f2016-09-05 23:19:05 +0200899 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000900 if can_clear_options():
Christian Heimes598894f2016-09-05 23:19:05 +0200901 ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
902 self.assertEqual(default, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000903 ctx.options = 0
Matthias Klosef7c56242016-06-12 23:40:00 -0700904 # Ubuntu has OP_NO_SSLv3 forced on by default
905 self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
Antoine Pitroub5218772010-05-21 09:56:06 +0000906 else:
907 with self.assertRaises(ValueError):
908 ctx.options = 0
909
Christian Heimes22587792013-11-21 23:56:13 +0100910 def test_verify_mode(self):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000911 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
912 # Default value
913 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
914 ctx.verify_mode = ssl.CERT_OPTIONAL
915 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
916 ctx.verify_mode = ssl.CERT_REQUIRED
917 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
918 ctx.verify_mode = ssl.CERT_NONE
919 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
920 with self.assertRaises(TypeError):
921 ctx.verify_mode = None
922 with self.assertRaises(ValueError):
923 ctx.verify_mode = 42
924
Christian Heimes2427b502013-11-23 11:24:32 +0100925 @unittest.skipUnless(have_verify_flags(),
926 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +0100927 def test_verify_flags(self):
928 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson990fcaa2015-03-04 22:49:41 -0500929 # default value
930 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
931 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +0100932 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
933 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
934 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
935 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
936 ctx.verify_flags = ssl.VERIFY_DEFAULT
937 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
938 # supports any value
939 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
940 self.assertEqual(ctx.verify_flags,
941 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
942 with self.assertRaises(TypeError):
943 ctx.verify_flags = None
944
Antoine Pitrou152efa22010-05-16 18:19:27 +0000945 def test_load_cert_chain(self):
946 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
947 # Combined key and cert in a single file
Benjamin Peterson1ea070e2014-11-03 21:05:01 -0500948 ctx.load_cert_chain(CERTFILE, keyfile=None)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000949 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
950 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200951 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000952 ctx.load_cert_chain(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000953 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000954 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000955 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000956 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000957 ctx.load_cert_chain(EMPTYCERT)
958 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000959 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000960 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
961 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
962 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000963 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000964 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000965 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000966 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000967 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000968 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
969 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000970 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000971 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Martin Panter3d81d932016-01-14 09:36:00 +0000972 ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200973 # Password protected key and cert
974 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
975 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
976 ctx.load_cert_chain(CERTFILE_PROTECTED,
977 password=bytearray(KEY_PASSWORD.encode()))
978 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
979 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
980 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
981 bytearray(KEY_PASSWORD.encode()))
982 with self.assertRaisesRegex(TypeError, "should be a string"):
983 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
984 with self.assertRaises(ssl.SSLError):
985 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
986 with self.assertRaisesRegex(ValueError, "cannot be longer"):
987 # openssl has a fixed limit on the password buffer.
988 # PEM_BUFSIZE is generally set to 1kb.
989 # Return a string larger than this.
990 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
991 # Password callback
992 def getpass_unicode():
993 return KEY_PASSWORD
994 def getpass_bytes():
995 return KEY_PASSWORD.encode()
996 def getpass_bytearray():
997 return bytearray(KEY_PASSWORD.encode())
998 def getpass_badpass():
999 return "badpass"
1000 def getpass_huge():
1001 return b'a' * (1024 * 1024)
1002 def getpass_bad_type():
1003 return 9
1004 def getpass_exception():
1005 raise Exception('getpass error')
1006 class GetPassCallable:
1007 def __call__(self):
1008 return KEY_PASSWORD
1009 def getpass(self):
1010 return KEY_PASSWORD
1011 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
1012 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
1013 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
1014 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
1015 ctx.load_cert_chain(CERTFILE_PROTECTED,
1016 password=GetPassCallable().getpass)
1017 with self.assertRaises(ssl.SSLError):
1018 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
1019 with self.assertRaisesRegex(ValueError, "cannot be longer"):
1020 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
1021 with self.assertRaisesRegex(TypeError, "must return a string"):
1022 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
1023 with self.assertRaisesRegex(Exception, "getpass error"):
1024 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
1025 # Make sure the password function isn't called if it isn't needed
1026 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001027
1028 def test_load_verify_locations(self):
1029 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1030 ctx.load_verify_locations(CERTFILE)
1031 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
1032 ctx.load_verify_locations(BYTES_CERTFILE)
1033 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
1034 self.assertRaises(TypeError, ctx.load_verify_locations)
Christian Heimesefff7062013-11-21 03:35:02 +01001035 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001036 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001037 ctx.load_verify_locations(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +00001038 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001039 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +00001040 ctx.load_verify_locations(BADCERT)
1041 ctx.load_verify_locations(CERTFILE, CAPATH)
1042 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
1043
Victor Stinner80f75e62011-01-29 11:31:20 +00001044 # Issue #10989: crash if the second argument type is invalid
1045 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
1046
Christian Heimesefff7062013-11-21 03:35:02 +01001047 def test_load_verify_cadata(self):
1048 # test cadata
1049 with open(CAFILE_CACERT) as f:
1050 cacert_pem = f.read()
1051 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
1052 with open(CAFILE_NEURONIO) as f:
1053 neuronio_pem = f.read()
1054 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
1055
1056 # test PEM
1057 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1058 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
1059 ctx.load_verify_locations(cadata=cacert_pem)
1060 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
1061 ctx.load_verify_locations(cadata=neuronio_pem)
1062 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1063 # cert already in hash table
1064 ctx.load_verify_locations(cadata=neuronio_pem)
1065 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1066
1067 # combined
1068 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1069 combined = "\n".join((cacert_pem, neuronio_pem))
1070 ctx.load_verify_locations(cadata=combined)
1071 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1072
1073 # with junk around the certs
1074 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1075 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
1076 neuronio_pem, "tail"]
1077 ctx.load_verify_locations(cadata="\n".join(combined))
1078 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1079
1080 # test DER
1081 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1082 ctx.load_verify_locations(cadata=cacert_der)
1083 ctx.load_verify_locations(cadata=neuronio_der)
1084 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1085 # cert already in hash table
1086 ctx.load_verify_locations(cadata=cacert_der)
1087 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1088
1089 # combined
1090 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1091 combined = b"".join((cacert_der, neuronio_der))
1092 ctx.load_verify_locations(cadata=combined)
1093 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1094
1095 # error cases
1096 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1097 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
1098
1099 with self.assertRaisesRegex(ssl.SSLError, "no start line"):
1100 ctx.load_verify_locations(cadata="broken")
1101 with self.assertRaisesRegex(ssl.SSLError, "not enough data"):
1102 ctx.load_verify_locations(cadata=b"broken")
1103
1104
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001105 def test_load_dh_params(self):
1106 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1107 ctx.load_dh_params(DHFILE)
1108 if os.name != 'nt':
1109 ctx.load_dh_params(BYTES_DHFILE)
1110 self.assertRaises(TypeError, ctx.load_dh_params)
1111 self.assertRaises(TypeError, ctx.load_dh_params, None)
1112 with self.assertRaises(FileNotFoundError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001113 ctx.load_dh_params(NONEXISTINGCERT)
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001114 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001115 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001116 ctx.load_dh_params(CERTFILE)
1117
Antoine Pitroueb585ad2010-10-22 18:24:20 +00001118 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +00001119 def test_session_stats(self):
1120 for proto in PROTOCOLS:
1121 ctx = ssl.SSLContext(proto)
1122 self.assertEqual(ctx.session_stats(), {
1123 'number': 0,
1124 'connect': 0,
1125 'connect_good': 0,
1126 'connect_renegotiate': 0,
1127 'accept': 0,
1128 'accept_good': 0,
1129 'accept_renegotiate': 0,
1130 'hits': 0,
1131 'misses': 0,
1132 'timeouts': 0,
1133 'cache_full': 0,
1134 })
1135
Antoine Pitrou664c2d12010-11-17 20:29:42 +00001136 def test_set_default_verify_paths(self):
1137 # There's not much we can do to test that it acts as expected,
1138 # so just check it doesn't crash or raise an exception.
1139 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1140 ctx.set_default_verify_paths()
1141
Antoine Pitrou501da612011-12-21 09:27:41 +01001142 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +01001143 def test_set_ecdh_curve(self):
1144 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1145 ctx.set_ecdh_curve("prime256v1")
1146 ctx.set_ecdh_curve(b"prime256v1")
1147 self.assertRaises(TypeError, ctx.set_ecdh_curve)
1148 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
1149 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
1150 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
1151
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001152 @needs_sni
1153 def test_sni_callback(self):
1154 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1155
1156 # set_servername_callback expects a callable, or None
1157 self.assertRaises(TypeError, ctx.set_servername_callback)
1158 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
1159 self.assertRaises(TypeError, ctx.set_servername_callback, "")
1160 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
1161
1162 def dummycallback(sock, servername, ctx):
1163 pass
1164 ctx.set_servername_callback(None)
1165 ctx.set_servername_callback(dummycallback)
1166
1167 @needs_sni
1168 def test_sni_callback_refcycle(self):
1169 # Reference cycles through the servername callback are detected
1170 # and cleared.
1171 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1172 def dummycallback(sock, servername, ctx, cycle=ctx):
1173 pass
1174 ctx.set_servername_callback(dummycallback)
1175 wr = weakref.ref(ctx)
1176 del ctx, dummycallback
1177 gc.collect()
1178 self.assertIs(wr(), None)
1179
Christian Heimes9a5395a2013-06-17 15:44:12 +02001180 def test_cert_store_stats(self):
1181 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1182 self.assertEqual(ctx.cert_store_stats(),
1183 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1184 ctx.load_cert_chain(CERTFILE)
1185 self.assertEqual(ctx.cert_store_stats(),
1186 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1187 ctx.load_verify_locations(CERTFILE)
1188 self.assertEqual(ctx.cert_store_stats(),
1189 {'x509_ca': 0, 'crl': 0, 'x509': 1})
Martin Panterb55f8b72016-01-14 12:53:56 +00001190 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001191 self.assertEqual(ctx.cert_store_stats(),
1192 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1193
1194 def test_get_ca_certs(self):
1195 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1196 self.assertEqual(ctx.get_ca_certs(), [])
1197 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1198 ctx.load_verify_locations(CERTFILE)
1199 self.assertEqual(ctx.get_ca_certs(), [])
Martin Panterb55f8b72016-01-14 12:53:56 +00001200 # but CAFILE_CACERT is a CA cert
1201 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001202 self.assertEqual(ctx.get_ca_certs(),
1203 [{'issuer': ((('organizationName', 'Root CA'),),
1204 (('organizationalUnitName', 'http://www.cacert.org'),),
1205 (('commonName', 'CA Cert Signing Authority'),),
1206 (('emailAddress', 'support@cacert.org'),)),
1207 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1208 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1209 'serialNumber': '00',
Christian Heimesbd3a7f92013-11-21 03:40:15 +01001210 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
Christian Heimes9a5395a2013-06-17 15:44:12 +02001211 'subject': ((('organizationName', 'Root CA'),),
1212 (('organizationalUnitName', 'http://www.cacert.org'),),
1213 (('commonName', 'CA Cert Signing Authority'),),
1214 (('emailAddress', 'support@cacert.org'),)),
1215 'version': 3}])
1216
Martin Panterb55f8b72016-01-14 12:53:56 +00001217 with open(CAFILE_CACERT) as f:
Christian Heimes9a5395a2013-06-17 15:44:12 +02001218 pem = f.read()
1219 der = ssl.PEM_cert_to_DER_cert(pem)
1220 self.assertEqual(ctx.get_ca_certs(True), [der])
1221
Christian Heimes72d28502013-11-23 13:56:58 +01001222 def test_load_default_certs(self):
1223 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1224 ctx.load_default_certs()
1225
1226 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1227 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1228 ctx.load_default_certs()
1229
1230 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1231 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1232
1233 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1234 self.assertRaises(TypeError, ctx.load_default_certs, None)
1235 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1236
Benjamin Peterson91244e02014-10-03 18:17:15 -04001237 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Christian Heimes598894f2016-09-05 23:19:05 +02001238 @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
Benjamin Peterson5915b0f2014-10-03 17:27:05 -04001239 def test_load_default_certs_env(self):
1240 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1241 with support.EnvironmentVarGuard() as env:
1242 env["SSL_CERT_DIR"] = CAPATH
1243 env["SSL_CERT_FILE"] = CERTFILE
1244 ctx.load_default_certs()
1245 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1246
Benjamin Peterson91244e02014-10-03 18:17:15 -04001247 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
1248 def test_load_default_certs_env_windows(self):
1249 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1250 ctx.load_default_certs()
1251 stats = ctx.cert_store_stats()
1252
1253 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1254 with support.EnvironmentVarGuard() as env:
1255 env["SSL_CERT_DIR"] = CAPATH
1256 env["SSL_CERT_FILE"] = CERTFILE
1257 ctx.load_default_certs()
1258 stats["x509"] += 1
1259 self.assertEqual(ctx.cert_store_stats(), stats)
1260
Christian Heimes358cfd42016-09-10 22:43:48 +02001261 def _assert_context_options(self, ctx):
1262 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1263 if OP_NO_COMPRESSION != 0:
1264 self.assertEqual(ctx.options & OP_NO_COMPRESSION,
1265 OP_NO_COMPRESSION)
1266 if OP_SINGLE_DH_USE != 0:
1267 self.assertEqual(ctx.options & OP_SINGLE_DH_USE,
1268 OP_SINGLE_DH_USE)
1269 if OP_SINGLE_ECDH_USE != 0:
1270 self.assertEqual(ctx.options & OP_SINGLE_ECDH_USE,
1271 OP_SINGLE_ECDH_USE)
1272 if OP_CIPHER_SERVER_PREFERENCE != 0:
1273 self.assertEqual(ctx.options & OP_CIPHER_SERVER_PREFERENCE,
1274 OP_CIPHER_SERVER_PREFERENCE)
1275
Christian Heimes4c05b472013-11-23 15:58:30 +01001276 def test_create_default_context(self):
1277 ctx = ssl.create_default_context()
Christian Heimes358cfd42016-09-10 22:43:48 +02001278
Donald Stufft6a2ba942014-03-23 19:05:28 -04001279 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001280 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001281 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001282 self._assert_context_options(ctx)
1283
Christian Heimes4c05b472013-11-23 15:58:30 +01001284
1285 with open(SIGNING_CA) as f:
1286 cadata = f.read()
1287 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1288 cadata=cadata)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001289 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001290 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes358cfd42016-09-10 22:43:48 +02001291 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001292
1293 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001294 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001295 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001296 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001297
Christian Heimes67986f92013-11-23 22:43:47 +01001298 def test__create_stdlib_context(self):
1299 ctx = ssl._create_stdlib_context()
1300 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1301 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001302 self.assertFalse(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001303 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001304
1305 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1306 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1307 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001308 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001309
1310 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001311 cert_reqs=ssl.CERT_REQUIRED,
1312 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001313 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1314 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001315 self.assertTrue(ctx.check_hostname)
Christian Heimes358cfd42016-09-10 22:43:48 +02001316 self._assert_context_options(ctx)
Christian Heimes67986f92013-11-23 22:43:47 +01001317
1318 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1319 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1320 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes358cfd42016-09-10 22:43:48 +02001321 self._assert_context_options(ctx)
Christian Heimes4c05b472013-11-23 15:58:30 +01001322
Christian Heimes1aa9a752013-12-02 02:41:19 +01001323 def test_check_hostname(self):
1324 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1325 self.assertFalse(ctx.check_hostname)
1326
1327 # Requires CERT_REQUIRED or CERT_OPTIONAL
1328 with self.assertRaises(ValueError):
1329 ctx.check_hostname = True
1330 ctx.verify_mode = ssl.CERT_REQUIRED
1331 self.assertFalse(ctx.check_hostname)
1332 ctx.check_hostname = True
1333 self.assertTrue(ctx.check_hostname)
1334
1335 ctx.verify_mode = ssl.CERT_OPTIONAL
1336 ctx.check_hostname = True
1337 self.assertTrue(ctx.check_hostname)
1338
1339 # Cannot set CERT_NONE with check_hostname enabled
1340 with self.assertRaises(ValueError):
1341 ctx.verify_mode = ssl.CERT_NONE
1342 ctx.check_hostname = False
1343 self.assertFalse(ctx.check_hostname)
1344
Christian Heimes5fe668c2016-09-12 00:01:11 +02001345 def test_context_client_server(self):
1346 # PROTOCOL_TLS_CLIENT has sane defaults
1347 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
1348 self.assertTrue(ctx.check_hostname)
1349 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1350
1351 # PROTOCOL_TLS_SERVER has different but also sane defaults
1352 ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
1353 self.assertFalse(ctx.check_hostname)
1354 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1355
Antoine Pitrou152efa22010-05-16 18:19:27 +00001356
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001357class SSLErrorTests(unittest.TestCase):
1358
1359 def test_str(self):
1360 # The str() of a SSLError doesn't include the errno
1361 e = ssl.SSLError(1, "foo")
1362 self.assertEqual(str(e), "foo")
1363 self.assertEqual(e.errno, 1)
1364 # Same for a subclass
1365 e = ssl.SSLZeroReturnError(1, "foo")
1366 self.assertEqual(str(e), "foo")
1367 self.assertEqual(e.errno, 1)
1368
1369 def test_lib_reason(self):
1370 # Test the library and reason attributes
1371 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1372 with self.assertRaises(ssl.SSLError) as cm:
1373 ctx.load_dh_params(CERTFILE)
1374 self.assertEqual(cm.exception.library, 'PEM')
1375 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1376 s = str(cm.exception)
1377 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1378
1379 def test_subclass(self):
1380 # Check that the appropriate SSLError subclass is raised
1381 # (this only tests one of them)
1382 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1383 with socket.socket() as s:
1384 s.bind(("127.0.0.1", 0))
Charles-François Natali6e204602014-07-23 19:28:13 +01001385 s.listen()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001386 c = socket.socket()
1387 c.connect(s.getsockname())
1388 c.setblocking(False)
1389 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001390 with self.assertRaises(ssl.SSLWantReadError) as cm:
1391 c.do_handshake()
1392 s = str(cm.exception)
1393 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1394 # For compatibility
1395 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1396
1397
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001398class MemoryBIOTests(unittest.TestCase):
1399
1400 def test_read_write(self):
1401 bio = ssl.MemoryBIO()
1402 bio.write(b'foo')
1403 self.assertEqual(bio.read(), b'foo')
1404 self.assertEqual(bio.read(), b'')
1405 bio.write(b'foo')
1406 bio.write(b'bar')
1407 self.assertEqual(bio.read(), b'foobar')
1408 self.assertEqual(bio.read(), b'')
1409 bio.write(b'baz')
1410 self.assertEqual(bio.read(2), b'ba')
1411 self.assertEqual(bio.read(1), b'z')
1412 self.assertEqual(bio.read(1), b'')
1413
1414 def test_eof(self):
1415 bio = ssl.MemoryBIO()
1416 self.assertFalse(bio.eof)
1417 self.assertEqual(bio.read(), b'')
1418 self.assertFalse(bio.eof)
1419 bio.write(b'foo')
1420 self.assertFalse(bio.eof)
1421 bio.write_eof()
1422 self.assertFalse(bio.eof)
1423 self.assertEqual(bio.read(2), b'fo')
1424 self.assertFalse(bio.eof)
1425 self.assertEqual(bio.read(1), b'o')
1426 self.assertTrue(bio.eof)
1427 self.assertEqual(bio.read(), b'')
1428 self.assertTrue(bio.eof)
1429
1430 def test_pending(self):
1431 bio = ssl.MemoryBIO()
1432 self.assertEqual(bio.pending, 0)
1433 bio.write(b'foo')
1434 self.assertEqual(bio.pending, 3)
1435 for i in range(3):
1436 bio.read(1)
1437 self.assertEqual(bio.pending, 3-i-1)
1438 for i in range(3):
1439 bio.write(b'x')
1440 self.assertEqual(bio.pending, i+1)
1441 bio.read()
1442 self.assertEqual(bio.pending, 0)
1443
1444 def test_buffer_types(self):
1445 bio = ssl.MemoryBIO()
1446 bio.write(b'foo')
1447 self.assertEqual(bio.read(), b'foo')
1448 bio.write(bytearray(b'bar'))
1449 self.assertEqual(bio.read(), b'bar')
1450 bio.write(memoryview(b'baz'))
1451 self.assertEqual(bio.read(), b'baz')
1452
1453 def test_error_types(self):
1454 bio = ssl.MemoryBIO()
1455 self.assertRaises(TypeError, bio.write, 'foo')
1456 self.assertRaises(TypeError, bio.write, None)
1457 self.assertRaises(TypeError, bio.write, True)
1458 self.assertRaises(TypeError, bio.write, 1)
1459
1460
Martin Panter3840b2a2016-03-27 01:53:46 +00001461@unittest.skipUnless(_have_threads, "Needs threading module")
1462class SimpleBackgroundTests(unittest.TestCase):
1463
1464 """Tests that connect to a simple server running in the background"""
1465
1466 def setUp(self):
1467 server = ThreadedEchoServer(SIGNED_CERTFILE)
1468 self.server_addr = (HOST, server.port)
1469 server.__enter__()
1470 self.addCleanup(server.__exit__, None, None, None)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001471
Antoine Pitrou480a1242010-04-28 21:37:09 +00001472 def test_connect(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001473 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001474 cert_reqs=ssl.CERT_NONE) as s:
1475 s.connect(self.server_addr)
1476 self.assertEqual({}, s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001477 self.assertFalse(s.server_side)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001478
Martin Panter3840b2a2016-03-27 01:53:46 +00001479 # this should succeed because we specify the root cert
Christian Heimesd0486372016-09-10 23:23:33 +02001480 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001481 cert_reqs=ssl.CERT_REQUIRED,
1482 ca_certs=SIGNING_CA) as s:
1483 s.connect(self.server_addr)
1484 self.assertTrue(s.getpeercert())
Christian Heimesa5d07652016-09-24 10:48:05 +02001485 self.assertFalse(s.server_side)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001486
Martin Panter3840b2a2016-03-27 01:53:46 +00001487 def test_connect_fail(self):
1488 # This should fail because we have no verification certs. Connection
1489 # failure crashes ThreadedEchoServer, so run this in an independent
1490 # test method.
Christian Heimesd0486372016-09-10 23:23:33 +02001491 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001492 cert_reqs=ssl.CERT_REQUIRED)
1493 self.addCleanup(s.close)
1494 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1495 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001496
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001497 def test_connect_ex(self):
1498 # Issue #11326: check connect_ex() implementation
Christian Heimesd0486372016-09-10 23:23:33 +02001499 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001500 cert_reqs=ssl.CERT_REQUIRED,
1501 ca_certs=SIGNING_CA)
1502 self.addCleanup(s.close)
1503 self.assertEqual(0, s.connect_ex(self.server_addr))
1504 self.assertTrue(s.getpeercert())
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001505
1506 def test_non_blocking_connect_ex(self):
1507 # Issue #11326: non-blocking connect_ex() should allow handshake
1508 # to proceed after the socket gets ready.
Christian Heimesd0486372016-09-10 23:23:33 +02001509 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001510 cert_reqs=ssl.CERT_REQUIRED,
1511 ca_certs=SIGNING_CA,
1512 do_handshake_on_connect=False)
1513 self.addCleanup(s.close)
1514 s.setblocking(False)
1515 rc = s.connect_ex(self.server_addr)
1516 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1517 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
1518 # Wait for connect to finish
1519 select.select([], [s], [], 5.0)
1520 # Non-blocking handshake
1521 while True:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001522 try:
Martin Panter3840b2a2016-03-27 01:53:46 +00001523 s.do_handshake()
1524 break
1525 except ssl.SSLWantReadError:
1526 select.select([s], [], [], 5.0)
1527 except ssl.SSLWantWriteError:
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001528 select.select([], [s], [], 5.0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001529 # SSL established
1530 self.assertTrue(s.getpeercert())
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001531
Antoine Pitrou152efa22010-05-16 18:19:27 +00001532 def test_connect_with_context(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001533 # Same as test_connect, but with a separately created context
1534 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1535 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1536 s.connect(self.server_addr)
1537 self.assertEqual({}, s.getpeercert())
1538 # Same with a server hostname
1539 with ctx.wrap_socket(socket.socket(socket.AF_INET),
1540 server_hostname="dummy") as s:
1541 s.connect(self.server_addr)
1542 ctx.verify_mode = ssl.CERT_REQUIRED
1543 # This should succeed because we specify the root cert
1544 ctx.load_verify_locations(SIGNING_CA)
1545 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1546 s.connect(self.server_addr)
1547 cert = s.getpeercert()
1548 self.assertTrue(cert)
1549
1550 def test_connect_with_context_fail(self):
1551 # This should fail because we have no verification certs. Connection
1552 # failure crashes ThreadedEchoServer, so run this in an independent
1553 # test method.
1554 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1555 ctx.verify_mode = ssl.CERT_REQUIRED
1556 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1557 self.addCleanup(s.close)
1558 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1559 s.connect, self.server_addr)
Antoine Pitrou152efa22010-05-16 18:19:27 +00001560
1561 def test_connect_capath(self):
1562 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001563 # NOTE: the subject hashing algorithm has been changed between
1564 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1565 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001566 # filename) for this test to be portable across OpenSSL releases.
Martin Panter3840b2a2016-03-27 01:53:46 +00001567 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1568 ctx.verify_mode = ssl.CERT_REQUIRED
1569 ctx.load_verify_locations(capath=CAPATH)
1570 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1571 s.connect(self.server_addr)
1572 cert = s.getpeercert()
1573 self.assertTrue(cert)
1574 # Same with a bytes `capath` argument
1575 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1576 ctx.verify_mode = ssl.CERT_REQUIRED
1577 ctx.load_verify_locations(capath=BYTES_CAPATH)
1578 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1579 s.connect(self.server_addr)
1580 cert = s.getpeercert()
1581 self.assertTrue(cert)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001582
Christian Heimesefff7062013-11-21 03:35:02 +01001583 def test_connect_cadata(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001584 with open(SIGNING_CA) as f:
Christian Heimesefff7062013-11-21 03:35:02 +01001585 pem = f.read()
1586 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panter3840b2a2016-03-27 01:53:46 +00001587 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1588 ctx.verify_mode = ssl.CERT_REQUIRED
1589 ctx.load_verify_locations(cadata=pem)
1590 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1591 s.connect(self.server_addr)
1592 cert = s.getpeercert()
1593 self.assertTrue(cert)
Christian Heimesefff7062013-11-21 03:35:02 +01001594
Martin Panter3840b2a2016-03-27 01:53:46 +00001595 # same with DER
1596 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1597 ctx.verify_mode = ssl.CERT_REQUIRED
1598 ctx.load_verify_locations(cadata=der)
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
Antoine Pitroue3220242010-04-24 11:13:53 +00001604 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1605 def test_makefile_close(self):
1606 # Issue #5238: creating a file-like object with makefile() shouldn't
1607 # delay closing the underlying "real socket" (here tested with its
1608 # file descriptor, hence skipping the test under Windows).
Christian Heimesd0486372016-09-10 23:23:33 +02001609 ss = test_wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3840b2a2016-03-27 01:53:46 +00001610 ss.connect(self.server_addr)
1611 fd = ss.fileno()
1612 f = ss.makefile()
1613 f.close()
1614 # The fd is still open
1615 os.read(fd, 0)
1616 # Closing the SSL socket should close the fd too
1617 ss.close()
1618 gc.collect()
1619 with self.assertRaises(OSError) as e:
Antoine Pitroue3220242010-04-24 11:13:53 +00001620 os.read(fd, 0)
Martin Panter3840b2a2016-03-27 01:53:46 +00001621 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001622
Antoine Pitrou480a1242010-04-28 21:37:09 +00001623 def test_non_blocking_handshake(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001624 s = socket.socket(socket.AF_INET)
1625 s.connect(self.server_addr)
1626 s.setblocking(False)
Christian Heimesd0486372016-09-10 23:23:33 +02001627 s = test_wrap_socket(s,
Martin Panter3840b2a2016-03-27 01:53:46 +00001628 cert_reqs=ssl.CERT_NONE,
1629 do_handshake_on_connect=False)
1630 self.addCleanup(s.close)
1631 count = 0
1632 while True:
1633 try:
1634 count += 1
1635 s.do_handshake()
1636 break
1637 except ssl.SSLWantReadError:
1638 select.select([s], [], [])
1639 except ssl.SSLWantWriteError:
1640 select.select([], [s], [])
1641 if support.verbose:
1642 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001643
Antoine Pitrou480a1242010-04-28 21:37:09 +00001644 def test_get_server_certificate(self):
Martin Panter3840b2a2016-03-27 01:53:46 +00001645 _test_get_server_certificate(self, *self.server_addr, cert=SIGNING_CA)
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001646
Martin Panter3840b2a2016-03-27 01:53:46 +00001647 def test_get_server_certificate_fail(self):
1648 # Connection failure crashes ThreadedEchoServer, so run this in an
1649 # independent test method
1650 _test_get_server_certificate_fail(self, *self.server_addr)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001651
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001652 def test_ciphers(self):
Christian Heimesd0486372016-09-10 23:23:33 +02001653 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001654 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1655 s.connect(self.server_addr)
Christian Heimesd0486372016-09-10 23:23:33 +02001656 with test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001657 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1658 s.connect(self.server_addr)
1659 # Error checking can happen at instantiation or when connecting
1660 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
1661 with socket.socket(socket.AF_INET) as sock:
Christian Heimesd0486372016-09-10 23:23:33 +02001662 s = test_wrap_socket(sock,
Martin Panter3840b2a2016-03-27 01:53:46 +00001663 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1664 s.connect(self.server_addr)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001665
Christian Heimes9a5395a2013-06-17 15:44:12 +02001666 def test_get_ca_certs_capath(self):
1667 # capath certs are loaded on request
Martin Panter3840b2a2016-03-27 01:53:46 +00001668 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1669 ctx.verify_mode = ssl.CERT_REQUIRED
1670 ctx.load_verify_locations(capath=CAPATH)
1671 self.assertEqual(ctx.get_ca_certs(), [])
1672 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1673 s.connect(self.server_addr)
1674 cert = s.getpeercert()
1675 self.assertTrue(cert)
1676 self.assertEqual(len(ctx.get_ca_certs()), 1)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001677
Christian Heimes575596e2013-12-15 21:49:17 +01001678 @needs_sni
Christian Heimes8e7f3942013-12-05 07:41:08 +01001679 def test_context_setget(self):
1680 # Check that the context of a connected socket can be replaced.
Martin Panter3840b2a2016-03-27 01:53:46 +00001681 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1682 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1683 s = socket.socket(socket.AF_INET)
1684 with ctx1.wrap_socket(s) as ss:
1685 ss.connect(self.server_addr)
1686 self.assertIs(ss.context, ctx1)
1687 self.assertIs(ss._sslobj.context, ctx1)
1688 ss.context = ctx2
1689 self.assertIs(ss.context, ctx2)
1690 self.assertIs(ss._sslobj.context, ctx2)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001691
1692 def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs):
1693 # A simple IO loop. Call func(*args) depending on the error we get
1694 # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs.
1695 timeout = kwargs.get('timeout', 10)
1696 count = 0
1697 while True:
1698 errno = None
1699 count += 1
1700 try:
1701 ret = func(*args)
1702 except ssl.SSLError as e:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001703 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
Martin Panter40b97ec2016-01-14 13:05:46 +00001704 ssl.SSL_ERROR_WANT_WRITE):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001705 raise
1706 errno = e.errno
1707 # Get any data from the outgoing BIO irrespective of any error, and
1708 # send it to the socket.
1709 buf = outgoing.read()
1710 sock.sendall(buf)
1711 # If there's no error, we're done. For WANT_READ, we need to get
1712 # data from the socket and put it in the incoming BIO.
1713 if errno is None:
1714 break
1715 elif errno == ssl.SSL_ERROR_WANT_READ:
1716 buf = sock.recv(32768)
1717 if buf:
1718 incoming.write(buf)
1719 else:
1720 incoming.write_eof()
1721 if support.verbose:
1722 sys.stdout.write("Needed %d calls to complete %s().\n"
1723 % (count, func.__name__))
1724 return ret
1725
Martin Panter3840b2a2016-03-27 01:53:46 +00001726 def test_bio_handshake(self):
1727 sock = socket.socket(socket.AF_INET)
1728 self.addCleanup(sock.close)
1729 sock.connect(self.server_addr)
1730 incoming = ssl.MemoryBIO()
1731 outgoing = ssl.MemoryBIO()
1732 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1733 ctx.verify_mode = ssl.CERT_REQUIRED
1734 ctx.load_verify_locations(SIGNING_CA)
1735 ctx.check_hostname = True
1736 sslobj = ctx.wrap_bio(incoming, outgoing, False, 'localhost')
1737 self.assertIs(sslobj._sslobj.owner, sslobj)
1738 self.assertIsNone(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001739 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001740 self.assertRaises(ValueError, sslobj.getpeercert)
1741 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1742 self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
1743 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1744 self.assertTrue(sslobj.cipher())
Christian Heimes01113fa2016-09-05 23:23:24 +02001745 self.assertIsNotNone(sslobj.shared_ciphers())
Martin Panter3840b2a2016-03-27 01:53:46 +00001746 self.assertTrue(sslobj.getpeercert())
1747 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1748 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
1749 try:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001750 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Martin Panter3840b2a2016-03-27 01:53:46 +00001751 except ssl.SSLSyscallError:
1752 # If the server shuts down the TCP connection without sending a
1753 # secure shutdown message, this is reported as SSL_ERROR_SYSCALL
1754 pass
1755 self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
1756
1757 def test_bio_read_write_data(self):
1758 sock = socket.socket(socket.AF_INET)
1759 self.addCleanup(sock.close)
1760 sock.connect(self.server_addr)
1761 incoming = ssl.MemoryBIO()
1762 outgoing = ssl.MemoryBIO()
1763 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1764 ctx.verify_mode = ssl.CERT_NONE
1765 sslobj = ctx.wrap_bio(incoming, outgoing, False)
1766 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1767 req = b'FOO\n'
1768 self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req)
1769 buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024)
1770 self.assertEqual(buf, b'foo\n')
1771 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001772
1773
Martin Panter3840b2a2016-03-27 01:53:46 +00001774class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001775
Martin Panter3840b2a2016-03-27 01:53:46 +00001776 def test_timeout_connect_ex(self):
1777 # Issue #12065: on a timeout, connect_ex() should return the original
1778 # errno (mimicking the behaviour of non-SSL sockets).
1779 with support.transient_internet(REMOTE_HOST):
Christian Heimesd0486372016-09-10 23:23:33 +02001780 s = test_wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3840b2a2016-03-27 01:53:46 +00001781 cert_reqs=ssl.CERT_REQUIRED,
1782 do_handshake_on_connect=False)
1783 self.addCleanup(s.close)
1784 s.settimeout(0.0000001)
1785 rc = s.connect_ex((REMOTE_HOST, 443))
1786 if rc == 0:
1787 self.skipTest("REMOTE_HOST responded too quickly")
1788 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1789
1790 @unittest.skipUnless(support.IPV6_ENABLED, 'Needs IPv6')
1791 def test_get_server_certificate_ipv6(self):
1792 with support.transient_internet('ipv6.google.com'):
1793 _test_get_server_certificate(self, 'ipv6.google.com', 443)
1794 _test_get_server_certificate_fail(self, 'ipv6.google.com', 443)
1795
1796 def test_algorithms(self):
1797 # Issue #8484: all algorithms should be available when verifying a
1798 # certificate.
1799 # SHA256 was added in OpenSSL 0.9.8
1800 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1801 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
1802 # sha256.tbs-internet.com needs SNI to use the correct certificate
1803 if not ssl.HAS_SNI:
1804 self.skipTest("SNI needed for this test")
1805 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1806 remote = ("sha256.tbs-internet.com", 443)
1807 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
1808 with support.transient_internet("sha256.tbs-internet.com"):
1809 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1810 ctx.verify_mode = ssl.CERT_REQUIRED
1811 ctx.load_verify_locations(sha256_cert)
1812 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1813 server_hostname="sha256.tbs-internet.com")
1814 try:
1815 s.connect(remote)
1816 if support.verbose:
1817 sys.stdout.write("\nCipher with %r is %r\n" %
1818 (remote, s.cipher()))
1819 sys.stdout.write("Certificate is:\n%s\n" %
1820 pprint.pformat(s.getpeercert()))
1821 finally:
1822 s.close()
1823
1824
1825def _test_get_server_certificate(test, host, port, cert=None):
1826 pem = ssl.get_server_certificate((host, port))
1827 if not pem:
1828 test.fail("No server certificate on %s:%s!" % (host, port))
1829
1830 pem = ssl.get_server_certificate((host, port), ca_certs=cert)
1831 if not pem:
1832 test.fail("No server certificate on %s:%s!" % (host, port))
1833 if support.verbose:
1834 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
1835
1836def _test_get_server_certificate_fail(test, host, port):
1837 try:
1838 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
1839 except ssl.SSLError as x:
1840 #should fail
1841 if support.verbose:
1842 sys.stdout.write("%s\n" % x)
1843 else:
1844 test.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1845
1846
1847if _have_threads:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001848 from test.ssl_servers import make_https_server
1849
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001850 class ThreadedEchoServer(threading.Thread):
1851
1852 class ConnectionHandler(threading.Thread):
1853
1854 """A mildly complicated class, because we want it to work both
1855 with and without the SSL wrapper around the socket connection, so
1856 that we can test the STARTTLS functionality."""
1857
Bill Janssen6e027db2007-11-15 22:23:56 +00001858 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001859 self.server = server
1860 self.running = False
1861 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001862 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001863 self.sock.setblocking(1)
1864 self.sslconn = None
1865 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001866 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001867
Antoine Pitrou480a1242010-04-28 21:37:09 +00001868 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001869 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001870 self.sslconn = self.server.context.wrap_socket(
1871 self.sock, server_side=True)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001872 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1873 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001874 except (ssl.SSLError, ConnectionResetError) as e:
1875 # We treat ConnectionResetError as though it were an
1876 # SSLError - OpenSSL on Ubuntu abruptly closes the
1877 # connection when asked to use an unsupported protocol.
1878 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001879 # XXX Various errors can have happened here, for example
1880 # a mismatching protocol version, an invalid certificate,
1881 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001882 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001883 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001884 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001885 self.running = False
1886 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001887 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001888 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001889 else:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001890 self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
Antoine Pitroub5218772010-05-21 09:56:06 +00001891 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001892 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001893 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001894 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1895 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001896 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001897 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1898 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001899 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001900 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001901 sys.stdout.write(" server: selected protocol is now "
1902 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001903 return True
1904
1905 def read(self):
1906 if self.sslconn:
1907 return self.sslconn.read()
1908 else:
1909 return self.sock.recv(1024)
1910
1911 def write(self, bytes):
1912 if self.sslconn:
1913 return self.sslconn.write(bytes)
1914 else:
1915 return self.sock.send(bytes)
1916
1917 def close(self):
1918 if self.sslconn:
1919 self.sslconn.close()
1920 else:
1921 self.sock.close()
1922
Antoine Pitrou480a1242010-04-28 21:37:09 +00001923 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001924 self.running = True
1925 if not self.server.starttls_server:
1926 if not self.wrap_conn():
1927 return
1928 while self.running:
1929 try:
1930 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001931 stripped = msg.strip()
1932 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001933 # eof, so quit this handler
1934 self.running = False
Martin Panter3840b2a2016-03-27 01:53:46 +00001935 try:
1936 self.sock = self.sslconn.unwrap()
1937 except OSError:
1938 # Many tests shut the TCP connection down
1939 # without an SSL shutdown. This causes
1940 # unwrap() to raise OSError with errno=0!
1941 pass
1942 else:
1943 self.sslconn = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001944 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001945 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001946 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001947 sys.stdout.write(" server: client closed connection\n")
1948 self.close()
1949 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001950 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001951 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001952 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001953 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001954 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001955 if not self.wrap_conn():
1956 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001957 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001958 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001959 if support.verbose and self.server.connectionchatty:
1960 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001961 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001962 self.sock = self.sslconn.unwrap()
1963 self.sslconn = None
1964 if support.verbose and self.server.connectionchatty:
1965 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001966 elif stripped == b'CB tls-unique':
1967 if support.verbose and self.server.connectionchatty:
1968 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1969 data = self.sslconn.get_channel_binding("tls-unique")
1970 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001971 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001972 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001973 self.server.connectionchatty):
1974 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001975 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1976 % (msg, ctype, msg.lower(), ctype))
1977 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001978 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001979 if self.server.chatty:
1980 handle_error("Test server failure:\n")
1981 self.close()
1982 self.running = False
1983 # normally, we'd just stop here, but for the test
1984 # harness, we want to stop the server
1985 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001986
Antoine Pitroub5218772010-05-21 09:56:06 +00001987 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001988 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001989 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersoncca27322015-01-23 16:35:37 -05001990 npn_protocols=None, alpn_protocols=None,
1991 ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00001992 if context:
1993 self.context = context
1994 else:
1995 self.context = ssl.SSLContext(ssl_version
1996 if ssl_version is not None
1997 else ssl.PROTOCOL_TLSv1)
1998 self.context.verify_mode = (certreqs if certreqs is not None
1999 else ssl.CERT_NONE)
2000 if cacerts:
2001 self.context.load_verify_locations(cacerts)
2002 if certificate:
2003 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002004 if npn_protocols:
2005 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05002006 if alpn_protocols:
2007 self.context.set_alpn_protocols(alpn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00002008 if ciphers:
2009 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002010 self.chatty = chatty
2011 self.connectionchatty = connectionchatty
2012 self.starttls_server = starttls_server
2013 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002014 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002015 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002016 self.active = False
Benjamin Petersoncca27322015-01-23 16:35:37 -05002017 self.selected_npn_protocols = []
2018 self.selected_alpn_protocols = []
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002019 self.shared_ciphers = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002020 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002021 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002022 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002023
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002024 def __enter__(self):
2025 self.start(threading.Event())
2026 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002027 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002028
2029 def __exit__(self, *args):
2030 self.stop()
2031 self.join()
2032
Antoine Pitrou480a1242010-04-28 21:37:09 +00002033 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002034 self.flag = flag
2035 threading.Thread.start(self)
2036
Antoine Pitrou480a1242010-04-28 21:37:09 +00002037 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00002038 self.sock.settimeout(0.05)
Charles-François Natali6e204602014-07-23 19:28:13 +01002039 self.sock.listen()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002040 self.active = True
2041 if self.flag:
2042 # signal an event
2043 self.flag.set()
2044 while self.active:
2045 try:
2046 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002047 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002048 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00002049 + repr(connaddr) + '\n')
2050 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002051 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01002052 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002053 except socket.timeout:
2054 pass
2055 except KeyboardInterrupt:
2056 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00002057 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002058
Antoine Pitrou480a1242010-04-28 21:37:09 +00002059 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002060 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002061
Bill Janssen54cc54c2007-12-14 22:08:56 +00002062 class AsyncoreEchoServer(threading.Thread):
2063
2064 # this one's based on asyncore.dispatcher
2065
2066 class EchoServer (asyncore.dispatcher):
2067
2068 class ConnectionHandler (asyncore.dispatcher_with_send):
2069
2070 def __init__(self, conn, certfile):
Christian Heimesd0486372016-09-10 23:23:33 +02002071 self.socket = test_wrap_socket(conn, server_side=True,
Bill Janssen54cc54c2007-12-14 22:08:56 +00002072 certfile=certfile,
2073 do_handshake_on_connect=False)
2074 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002075 self._ssl_accepting = True
2076 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002077
2078 def readable(self):
2079 if isinstance(self.socket, ssl.SSLSocket):
2080 while self.socket.pending() > 0:
2081 self.handle_read_event()
2082 return True
2083
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002084 def _do_ssl_handshake(self):
2085 try:
2086 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02002087 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
2088 return
2089 except ssl.SSLEOFError:
2090 return self.handle_close()
2091 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002092 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002093 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002094 if err.args[0] == errno.ECONNABORTED:
2095 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002096 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002097 self._ssl_accepting = False
2098
2099 def handle_read(self):
2100 if self._ssl_accepting:
2101 self._do_ssl_handshake()
2102 else:
2103 data = self.recv(1024)
2104 if support.verbose:
2105 sys.stdout.write(" server: read %s from client\n" % repr(data))
2106 if not data:
2107 self.close()
2108 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002109 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00002110
2111 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00002112 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002113 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002114 sys.stdout.write(" server: closed connection %s\n" % self.socket)
2115
2116 def handle_error(self):
2117 raise
2118
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002119 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002120 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002121 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2122 self.port = support.bind_port(sock, '')
2123 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00002124 self.listen(5)
2125
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00002126 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002127 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002128 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
2129 self.ConnectionHandler(sock_obj, self.certfile)
2130
2131 def handle_error(self):
2132 raise
2133
Trent Nelson78520002008-04-10 20:54:35 +00002134 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002135 self.flag = None
2136 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002137 self.server = self.EchoServer(certfile)
2138 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00002139 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002140 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00002141
2142 def __str__(self):
2143 return "<%s %s>" % (self.__class__.__name__, self.server)
2144
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002145 def __enter__(self):
2146 self.start(threading.Event())
2147 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002148 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002149
2150 def __exit__(self, *args):
2151 if support.verbose:
2152 sys.stdout.write(" cleanup: stopping server.\n")
2153 self.stop()
2154 if support.verbose:
2155 sys.stdout.write(" cleanup: joining server thread.\n")
2156 self.join()
2157 if support.verbose:
2158 sys.stdout.write(" cleanup: successfully joined.\n")
2159
Bill Janssen54cc54c2007-12-14 22:08:56 +00002160 def start (self, flag=None):
2161 self.flag = flag
2162 threading.Thread.start(self)
2163
Antoine Pitrou480a1242010-04-28 21:37:09 +00002164 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002165 self.active = True
2166 if self.flag:
2167 self.flag.set()
2168 while self.active:
2169 try:
2170 asyncore.loop(1)
2171 except:
2172 pass
2173
Antoine Pitrou480a1242010-04-28 21:37:09 +00002174 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002175 self.active = False
2176 self.server.close()
2177
Antoine Pitroub5218772010-05-21 09:56:06 +00002178 def server_params_test(client_context, server_context, indata=b"FOO\n",
Christian Heimes99a65702016-09-10 23:44:53 +02002179 chatty=True, connectionchatty=False, sni_name=None,
2180 session=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00002181 """
2182 Launch a server, connect a client to it and try various reads
2183 and writes.
2184 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002185 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00002186 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002187 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00002188 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002189 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002190 with client_context.wrap_socket(socket.socket(),
Christian Heimes99a65702016-09-10 23:44:53 +02002191 server_hostname=sni_name, session=session) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002192 s.connect((HOST, server.port))
2193 for arg in [indata, bytearray(indata), memoryview(indata)]:
2194 if connectionchatty:
2195 if support.verbose:
2196 sys.stdout.write(
2197 " client: sending %r...\n" % indata)
2198 s.write(arg)
2199 outdata = s.read()
2200 if connectionchatty:
2201 if support.verbose:
2202 sys.stdout.write(" client: read %r\n" % outdata)
2203 if outdata != indata.lower():
2204 raise AssertionError(
2205 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2206 % (outdata[:20], len(outdata),
2207 indata[:20].lower(), len(indata)))
2208 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00002209 if connectionchatty:
2210 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002211 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002212 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01002213 'compression': s.compression(),
2214 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002215 'peercert': s.getpeercert(),
Benjamin Petersoncca27322015-01-23 16:35:37 -05002216 'client_alpn_protocol': s.selected_alpn_protocol(),
Antoine Pitrou47e40422014-09-04 21:00:10 +02002217 'client_npn_protocol': s.selected_npn_protocol(),
2218 'version': s.version(),
Christian Heimes99a65702016-09-10 23:44:53 +02002219 'session_reused': s.session_reused,
2220 'session': s.session,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002221 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01002222 s.close()
Benjamin Petersoncca27322015-01-23 16:35:37 -05002223 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2224 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002225 stats['server_shared_ciphers'] = server.shared_ciphers
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002226 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00002227
Antoine Pitroub5218772010-05-21 09:56:06 +00002228 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2229 certsreqs=None, server_options=0, client_options=0):
Antoine Pitrou47e40422014-09-04 21:00:10 +02002230 """
2231 Try to SSL-connect using *client_protocol* to *server_protocol*.
2232 If *expect_success* is true, assert that the connection succeeds,
2233 if it's false, assert that the connection fails.
2234 Also, if *expect_success* is a string, assert that it is the protocol
2235 version actually used by the connection.
2236 """
Benjamin Peterson2a691a82008-03-31 01:51:45 +00002237 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002238 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00002239 certtype = {
2240 ssl.CERT_NONE: "CERT_NONE",
2241 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2242 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2243 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002244 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002245 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002246 sys.stdout.write(formatstr %
2247 (ssl.get_protocol_name(client_protocol),
2248 ssl.get_protocol_name(server_protocol),
2249 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00002250 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002251 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00002252 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002253 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002254
2255 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2256 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2257 # starting from OpenSSL 1.0.0 (see issue #8322).
2258 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2259 client_context.set_ciphers("ALL")
2260
Antoine Pitroub5218772010-05-21 09:56:06 +00002261 for ctx in (client_context, server_context):
2262 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00002263 ctx.load_cert_chain(CERTFILE)
2264 ctx.load_verify_locations(CERTFILE)
2265 try:
Antoine Pitrou47e40422014-09-04 21:00:10 +02002266 stats = server_params_test(client_context, server_context,
2267 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002268 # Protocol mismatch can result in either an SSLError, or a
2269 # "Connection reset by peer" error.
2270 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002271 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002272 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002273 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002274 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002275 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002276 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002277 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00002278 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002279 "Client protocol %s succeeded with server protocol %s!"
2280 % (ssl.get_protocol_name(client_protocol),
2281 ssl.get_protocol_name(server_protocol)))
Antoine Pitrou47e40422014-09-04 21:00:10 +02002282 elif (expect_success is not True
2283 and expect_success != stats['version']):
2284 raise AssertionError("version mismatch: expected %r, got %r"
2285 % (expect_success, stats['version']))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002286
2287
Bill Janssen6e027db2007-11-15 22:23:56 +00002288 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002289
Antoine Pitrou23df4832010-08-04 17:14:06 +00002290 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002291 def test_echo(self):
2292 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002293 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002294 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002295 for protocol in PROTOCOLS:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002296 if protocol in {ssl.PROTOCOL_TLS_CLIENT, ssl.PROTOCOL_TLS_SERVER}:
2297 continue
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01002298 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
2299 context = ssl.SSLContext(protocol)
2300 context.load_cert_chain(CERTFILE)
2301 server_params_test(context, context,
2302 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002303
Christian Heimes5fe668c2016-09-12 00:01:11 +02002304 client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
2305 client_context.load_verify_locations(SIGNING_CA)
2306 server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
2307 # server_context.load_verify_locations(SIGNING_CA)
2308 server_context.load_cert_chain(SIGNED_CERTFILE2)
2309
Christian Heimes9017ec12016-09-12 10:48:20 +02002310 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_SERVER):
Christian Heimes5fe668c2016-09-12 00:01:11 +02002311 server_params_test(client_context=client_context,
2312 server_context=server_context,
2313 chatty=True, connectionchatty=True,
2314 sni_name='fakehostname')
2315
Christian Heimes9017ec12016-09-12 10:48:20 +02002316 client_context.check_hostname = False
2317 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_CLIENT):
2318 with self.assertRaises(ssl.SSLError) as e:
Christian Heimes5fe668c2016-09-12 00:01:11 +02002319 server_params_test(client_context=server_context,
2320 server_context=client_context,
2321 chatty=True, connectionchatty=True,
2322 sni_name='fakehostname')
Christian Heimes9017ec12016-09-12 10:48:20 +02002323 self.assertIn('called a function you should not call',
2324 str(e.exception))
2325
2326 with self.subTest(client=ssl.PROTOCOL_TLS_SERVER, server=ssl.PROTOCOL_TLS_SERVER):
2327 with self.assertRaises(ssl.SSLError) as e:
2328 server_params_test(client_context=server_context,
2329 server_context=server_context,
2330 chatty=True, connectionchatty=True)
2331 self.assertIn('called a function you should not call',
2332 str(e.exception))
2333
2334 with self.subTest(client=ssl.PROTOCOL_TLS_CLIENT, server=ssl.PROTOCOL_TLS_CLIENT):
2335 with self.assertRaises(ssl.SSLError) as e:
2336 server_params_test(client_context=server_context,
2337 server_context=client_context,
2338 chatty=True, connectionchatty=True)
2339 self.assertIn('called a function you should not call',
2340 str(e.exception))
2341
Christian Heimes5fe668c2016-09-12 00:01:11 +02002342
Antoine Pitrou480a1242010-04-28 21:37:09 +00002343 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002344 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002345 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002346 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2347 context.verify_mode = ssl.CERT_REQUIRED
2348 context.load_verify_locations(CERTFILE)
2349 context.load_cert_chain(CERTFILE)
2350 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002351 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02002352 s = context.wrap_socket(socket.socket(),
2353 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002354 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02002355 # getpeercert() raise ValueError while the handshake isn't
2356 # done.
2357 with self.assertRaises(ValueError):
2358 s.getpeercert()
2359 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002360 cert = s.getpeercert()
2361 self.assertTrue(cert, "Can't get peer certificate.")
2362 cipher = s.cipher()
2363 if support.verbose:
2364 sys.stdout.write(pprint.pformat(cert) + '\n')
2365 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2366 if 'subject' not in cert:
2367 self.fail("No subject field in certificate: %s." %
2368 pprint.pformat(cert))
2369 if ((('organizationName', 'Python Software Foundation'),)
2370 not in cert['subject']):
2371 self.fail(
2372 "Missing or invalid 'organizationName' field in certificate subject; "
2373 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00002374 self.assertIn('notBefore', cert)
2375 self.assertIn('notAfter', cert)
2376 before = ssl.cert_time_to_seconds(cert['notBefore'])
2377 after = ssl.cert_time_to_seconds(cert['notAfter'])
2378 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002379 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002380
Christian Heimes2427b502013-11-23 11:24:32 +01002381 @unittest.skipUnless(have_verify_flags(),
2382 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01002383 def test_crl_check(self):
2384 if support.verbose:
2385 sys.stdout.write("\n")
2386
2387 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2388 server_context.load_cert_chain(SIGNED_CERTFILE)
2389
2390 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2391 context.verify_mode = ssl.CERT_REQUIRED
2392 context.load_verify_locations(SIGNING_CA)
Benjamin Petersonc3d9c5c2015-03-04 23:18:48 -05002393 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2394 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +01002395
2396 # VERIFY_DEFAULT should pass
2397 server = ThreadedEchoServer(context=server_context, chatty=True)
2398 with server:
2399 with context.wrap_socket(socket.socket()) as s:
2400 s.connect((HOST, server.port))
2401 cert = s.getpeercert()
2402 self.assertTrue(cert, "Can't get peer certificate.")
2403
2404 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01002405 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01002406
2407 server = ThreadedEchoServer(context=server_context, chatty=True)
2408 with server:
2409 with context.wrap_socket(socket.socket()) as s:
2410 with self.assertRaisesRegex(ssl.SSLError,
2411 "certificate verify failed"):
2412 s.connect((HOST, server.port))
2413
2414 # now load a CRL file. The CRL file is signed by the CA.
2415 context.load_verify_locations(CRLFILE)
2416
2417 server = ThreadedEchoServer(context=server_context, chatty=True)
2418 with server:
2419 with context.wrap_socket(socket.socket()) as s:
2420 s.connect((HOST, server.port))
2421 cert = s.getpeercert()
2422 self.assertTrue(cert, "Can't get peer certificate.")
2423
Christian Heimes1aa9a752013-12-02 02:41:19 +01002424 def test_check_hostname(self):
2425 if support.verbose:
2426 sys.stdout.write("\n")
2427
2428 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2429 server_context.load_cert_chain(SIGNED_CERTFILE)
2430
2431 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2432 context.verify_mode = ssl.CERT_REQUIRED
2433 context.check_hostname = True
2434 context.load_verify_locations(SIGNING_CA)
2435
2436 # correct hostname should verify
2437 server = ThreadedEchoServer(context=server_context, chatty=True)
2438 with server:
2439 with context.wrap_socket(socket.socket(),
2440 server_hostname="localhost") as s:
2441 s.connect((HOST, server.port))
2442 cert = s.getpeercert()
2443 self.assertTrue(cert, "Can't get peer certificate.")
2444
2445 # incorrect hostname should raise an exception
2446 server = ThreadedEchoServer(context=server_context, chatty=True)
2447 with server:
2448 with context.wrap_socket(socket.socket(),
2449 server_hostname="invalid") as s:
2450 with self.assertRaisesRegex(ssl.CertificateError,
2451 "hostname 'invalid' doesn't match 'localhost'"):
2452 s.connect((HOST, server.port))
2453
2454 # missing server_hostname arg should cause an exception, too
2455 server = ThreadedEchoServer(context=server_context, chatty=True)
2456 with server:
2457 with socket.socket() as s:
2458 with self.assertRaisesRegex(ValueError,
2459 "check_hostname requires server_hostname"):
2460 context.wrap_socket(s)
2461
Martin Panter407b62f2016-01-30 03:41:43 +00002462 def test_wrong_cert(self):
Martin Panter3464ea22016-02-01 21:58:11 +00002463 """Connecting when the server rejects the client's certificate
2464
2465 Launch a server with CERT_REQUIRED, and check that trying to
2466 connect to it with a wrong client certificate fails.
2467 """
2468 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2469 "wrongcert.pem")
2470 server = ThreadedEchoServer(CERTFILE,
2471 certreqs=ssl.CERT_REQUIRED,
2472 cacerts=CERTFILE, chatty=False,
2473 connectionchatty=False)
2474 with server, \
2475 socket.socket() as sock, \
Christian Heimesd0486372016-09-10 23:23:33 +02002476 test_wrap_socket(sock,
Martin Panter3464ea22016-02-01 21:58:11 +00002477 certfile=certfile,
2478 ssl_version=ssl.PROTOCOL_TLSv1) as s:
2479 try:
2480 # Expect either an SSL error about the server rejecting
2481 # the connection, or a low-level connection reset (which
2482 # sometimes happens on Windows)
2483 s.connect((HOST, server.port))
2484 except ssl.SSLError as e:
2485 if support.verbose:
2486 sys.stdout.write("\nSSLError is %r\n" % e)
2487 except OSError as e:
2488 if e.errno != errno.ECONNRESET:
2489 raise
2490 if support.verbose:
2491 sys.stdout.write("\nsocket.error is %r\n" % e)
2492 else:
2493 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002494
Antoine Pitrou480a1242010-04-28 21:37:09 +00002495 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002496 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002497 in the client when attempting handshake.
2498 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002499 listener_ready = threading.Event()
2500 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002501
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002502 s = socket.socket()
2503 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002504
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002505 # `listener` runs in a thread. It sits in an accept() until
2506 # the main thread connects. Then it rudely closes the socket,
2507 # and sets Event `listener_gone` to let the main thread know
2508 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002509 def listener():
Charles-François Natali6e204602014-07-23 19:28:13 +01002510 s.listen()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002511 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002512 newsock, addr = s.accept()
2513 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002514 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002515 listener_gone.set()
2516
2517 def connector():
2518 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002519 with socket.socket() as c:
2520 c.connect((HOST, port))
2521 listener_gone.wait()
2522 try:
Christian Heimesd0486372016-09-10 23:23:33 +02002523 ssl_sock = test_wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002524 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002525 pass
2526 else:
2527 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002528
2529 t = threading.Thread(target=listener)
2530 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002531 try:
2532 connector()
2533 finally:
2534 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002535
Antoine Pitrou23df4832010-08-04 17:14:06 +00002536 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002537 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2538 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002539 def test_protocol_sslv2(self):
2540 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002541 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002542 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002543 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2544 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2545 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002546 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Victor Stinner648b8622014-12-12 12:23:59 +01002547 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2548 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002549 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002550 # SSLv23 client with specific SSL options
2551 if no_sslv2_implies_sslv3_hello():
2552 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2553 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2554 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002555 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002556 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002557 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002558 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002559
Antoine Pitrou23df4832010-08-04 17:14:06 +00002560 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002561 def test_protocol_sslv23(self):
2562 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002563 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002564 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002565 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2566 try:
2567 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002568 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002569 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2570 if support.verbose:
2571 sys.stdout.write(
2572 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2573 % str(x))
Benjamin Petersone32467c2014-12-05 21:59:35 -05002574 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002575 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002576 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002577 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002578
Benjamin Petersone32467c2014-12-05 21:59:35 -05002579 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002580 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002581 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002582 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002583
Benjamin Petersone32467c2014-12-05 21:59:35 -05002584 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002585 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002586 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002587 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002588
Antoine Pitroub5218772010-05-21 09:56:06 +00002589 # Server with specific SSL options
Benjamin Petersone32467c2014-12-05 21:59:35 -05002590 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2591 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002592 server_options=ssl.OP_NO_SSLv3)
2593 # Will choose TLSv1
2594 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2595 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2596 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2597 server_options=ssl.OP_NO_TLSv1)
2598
2599
Antoine Pitrou23df4832010-08-04 17:14:06 +00002600 @skip_if_broken_ubuntu_ssl
Benjamin Petersone32467c2014-12-05 21:59:35 -05002601 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2602 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002603 def test_protocol_sslv3(self):
2604 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002605 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002606 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002607 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2608 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2609 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002610 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2611 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002612 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2613 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002614 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002615 if no_sslv2_implies_sslv3_hello():
2616 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002617 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2618 False, client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002619
Antoine Pitrou23df4832010-08-04 17:14:06 +00002620 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002621 def test_protocol_tlsv1(self):
2622 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002623 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002624 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002625 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2626 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2627 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002628 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2629 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002630 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2631 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002632 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2633 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002634
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002635 @skip_if_broken_ubuntu_ssl
2636 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2637 "TLS version 1.1 not supported.")
2638 def test_protocol_tlsv1_1(self):
2639 """Connecting to a TLSv1.1 server with various client options.
2640 Testing against older TLS versions."""
2641 if support.verbose:
2642 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002643 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002644 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2645 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002646 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2647 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002648 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2649 client_options=ssl.OP_NO_TLSv1_1)
2650
Antoine Pitrou47e40422014-09-04 21:00:10 +02002651 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002652 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2653 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2654
2655
2656 @skip_if_broken_ubuntu_ssl
2657 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2658 "TLS version 1.2 not supported.")
2659 def test_protocol_tlsv1_2(self):
2660 """Connecting to a TLSv1.2 server with various client options.
2661 Testing against older TLS versions."""
2662 if support.verbose:
2663 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002664 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002665 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2666 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2667 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2668 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002669 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2670 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002671 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2672 client_options=ssl.OP_NO_TLSv1_2)
2673
Antoine Pitrou47e40422014-09-04 21:00:10 +02002674 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002675 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2676 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2677 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2678 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2679
Antoine Pitrou480a1242010-04-28 21:37:09 +00002680 def test_starttls(self):
2681 """Switching from clear text to encrypted and back again."""
2682 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 +00002683
Trent Nelson78520002008-04-10 20:54:35 +00002684 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002685 ssl_version=ssl.PROTOCOL_TLSv1,
2686 starttls_server=True,
2687 chatty=True,
2688 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002689 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002690 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002691 s = socket.socket()
2692 s.setblocking(1)
2693 s.connect((HOST, server.port))
2694 if support.verbose:
2695 sys.stdout.write("\n")
2696 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002697 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002698 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002699 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002700 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002701 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002702 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002703 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002704 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002705 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002706 msg = outdata.strip().lower()
2707 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2708 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002709 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002710 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002711 " client: read %r from server, starting TLS...\n"
2712 % msg)
Christian Heimesd0486372016-09-10 23:23:33 +02002713 conn = test_wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002714 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002715 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2716 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002717 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002718 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002719 " client: read %r from server, ending TLS...\n"
2720 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002721 s = conn.unwrap()
2722 wrapped = False
2723 else:
2724 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002725 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002726 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002727 if support.verbose:
2728 sys.stdout.write(" client: closing connection.\n")
2729 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002730 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002731 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002732 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002733 if wrapped:
2734 conn.close()
2735 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002736 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002737
Antoine Pitrou480a1242010-04-28 21:37:09 +00002738 def test_socketserver(self):
Martin Panter463ef2b2016-09-22 09:37:56 +00002739 """Using socketserver to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002740 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002741 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002742 if support.verbose:
2743 sys.stdout.write('\n')
2744 with open(CERTFILE, 'rb') as f:
2745 d1 = f.read()
2746 d2 = ''
2747 # now fetch the same data from the HTTPS server
Benjamin Peterson4ffb0752014-11-03 14:29:33 -05002748 url = 'https://localhost:%d/%s' % (
2749 server.port, os.path.split(CERTFILE)[1])
2750 context = ssl.create_default_context(cafile=CERTFILE)
2751 f = urllib.request.urlopen(url, context=context)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002752 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002753 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002754 if dlen and (int(dlen) > 0):
2755 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002756 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002757 sys.stdout.write(
2758 " client: read %d bytes from remote server '%s'\n"
2759 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002760 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002761 f.close()
2762 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002763
Antoine Pitrou480a1242010-04-28 21:37:09 +00002764 def test_asyncore_server(self):
2765 """Check the example asyncore integration."""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002766 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002767 sys.stdout.write("\n")
2768
Antoine Pitrou480a1242010-04-28 21:37:09 +00002769 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002770 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002771 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002772 s = test_wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002773 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002774 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002775 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002776 " client: sending %r...\n" % indata)
2777 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002778 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002779 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002780 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002781 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002782 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002783 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2784 % (outdata[:20], len(outdata),
2785 indata[:20].lower(), len(indata)))
2786 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002787 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002788 sys.stdout.write(" client: closing connection.\n")
2789 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002790 if support.verbose:
2791 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002792
Antoine Pitrou480a1242010-04-28 21:37:09 +00002793 def test_recv_send(self):
2794 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002795 if support.verbose:
2796 sys.stdout.write("\n")
2797
2798 server = ThreadedEchoServer(CERTFILE,
2799 certreqs=ssl.CERT_NONE,
2800 ssl_version=ssl.PROTOCOL_TLSv1,
2801 cacerts=CERTFILE,
2802 chatty=True,
2803 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002804 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002805 s = test_wrap_socket(socket.socket(),
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002806 server_side=False,
2807 certfile=CERTFILE,
2808 ca_certs=CERTFILE,
2809 cert_reqs=ssl.CERT_NONE,
2810 ssl_version=ssl.PROTOCOL_TLSv1)
2811 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002812 # helper methods for standardising recv* method signatures
2813 def _recv_into():
2814 b = bytearray(b"\0"*100)
2815 count = s.recv_into(b)
2816 return b[:count]
2817
2818 def _recvfrom_into():
2819 b = bytearray(b"\0"*100)
2820 count, addr = s.recvfrom_into(b)
2821 return b[:count]
2822
Martin Panter519f9122016-04-03 02:12:54 +00002823 # (name, method, expect success?, *args, return value func)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002824 send_methods = [
Martin Panter519f9122016-04-03 02:12:54 +00002825 ('send', s.send, True, [], len),
2826 ('sendto', s.sendto, False, ["some.address"], len),
2827 ('sendall', s.sendall, True, [], lambda x: None),
Bill Janssen58afe4c2008-09-08 16:45:19 +00002828 ]
Martin Panter519f9122016-04-03 02:12:54 +00002829 # (name, method, whether to expect success, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002830 recv_methods = [
2831 ('recv', s.recv, True, []),
2832 ('recvfrom', s.recvfrom, False, ["some.address"]),
2833 ('recv_into', _recv_into, True, []),
2834 ('recvfrom_into', _recvfrom_into, False, []),
2835 ]
2836 data_prefix = "PREFIX_"
2837
Martin Panter519f9122016-04-03 02:12:54 +00002838 for (meth_name, send_meth, expect_success, args,
2839 ret_val_meth) in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002840 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002841 try:
Martin Panter519f9122016-04-03 02:12:54 +00002842 ret = send_meth(indata, *args)
2843 msg = "sending with {}".format(meth_name)
2844 self.assertEqual(ret, ret_val_meth(indata), msg=msg)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002845 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002846 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002847 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002848 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002849 "<<{outdata:r}>> ({nout:d}) received; "
2850 "expected <<{indata:r}>> ({nin:d})\n".format(
2851 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002852 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002853 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002854 )
2855 )
2856 except ValueError as e:
2857 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002858 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002859 "Failed to send with method <<{name:s}>>; "
2860 "expected to succeed.\n".format(name=meth_name)
2861 )
2862 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002863 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002864 "Method <<{name:s}>> failed with unexpected "
2865 "exception message: {exp:s}\n".format(
2866 name=meth_name, exp=e
2867 )
2868 )
2869
2870 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002871 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002872 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002873 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002874 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002875 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002876 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002877 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002878 "<<{outdata:r}>> ({nout:d}) received; "
2879 "expected <<{indata:r}>> ({nin:d})\n".format(
2880 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002881 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002882 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002883 )
2884 )
2885 except ValueError as e:
2886 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002887 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002888 "Failed to receive with method <<{name:s}>>; "
2889 "expected to succeed.\n".format(name=meth_name)
2890 )
2891 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002892 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002893 "Method <<{name:s}>> failed with unexpected "
2894 "exception message: {exp:s}\n".format(
2895 name=meth_name, exp=e
2896 )
2897 )
2898 # consume data
2899 s.read()
2900
Martin Panterf6b1d662016-03-28 00:22:09 +00002901 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panterbed7f1a2016-07-11 00:17:13 +00002902 data = b"data"
Martin Panter5503d472016-03-27 05:35:19 +00002903 s.send(data)
2904 buffer = bytearray(len(data))
2905 self.assertEqual(s.read(-1, buffer), len(data))
2906 self.assertEqual(buffer, data)
2907
Nick Coghlan513886a2011-08-28 00:00:27 +10002908 # Make sure sendmsg et al are disallowed to avoid
2909 # inadvertent disclosure of data and/or corruption
2910 # of the encrypted data stream
2911 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2912 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2913 self.assertRaises(NotImplementedError,
2914 s.recvmsg_into, bytearray(100))
2915
Antoine Pitrou480a1242010-04-28 21:37:09 +00002916 s.write(b"over\n")
Martin Panter5503d472016-03-27 05:35:19 +00002917
2918 self.assertRaises(ValueError, s.recv, -1)
2919 self.assertRaises(ValueError, s.read, -1)
2920
Bill Janssen58afe4c2008-09-08 16:45:19 +00002921 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002922
Martin Panterbed7f1a2016-07-11 00:17:13 +00002923 def test_recv_zero(self):
2924 server = ThreadedEchoServer(CERTFILE)
2925 server.__enter__()
2926 self.addCleanup(server.__exit__, None, None)
2927 s = socket.create_connection((HOST, server.port))
2928 self.addCleanup(s.close)
Christian Heimesd0486372016-09-10 23:23:33 +02002929 s = test_wrap_socket(s, suppress_ragged_eofs=False)
Martin Panterbed7f1a2016-07-11 00:17:13 +00002930 self.addCleanup(s.close)
2931
2932 # recv/read(0) should return no data
2933 s.send(b"data")
2934 self.assertEqual(s.recv(0), b"")
2935 self.assertEqual(s.read(0), b"")
2936 self.assertEqual(s.read(), b"data")
2937
2938 # Should not block if the other end sends no data
2939 s.setblocking(False)
2940 self.assertEqual(s.recv(0), b"")
2941 self.assertEqual(s.recv_into(bytearray()), 0)
2942
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002943 def test_nonblocking_send(self):
2944 server = ThreadedEchoServer(CERTFILE,
2945 certreqs=ssl.CERT_NONE,
2946 ssl_version=ssl.PROTOCOL_TLSv1,
2947 cacerts=CERTFILE,
2948 chatty=True,
2949 connectionchatty=False)
2950 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02002951 s = test_wrap_socket(socket.socket(),
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002952 server_side=False,
2953 certfile=CERTFILE,
2954 ca_certs=CERTFILE,
2955 cert_reqs=ssl.CERT_NONE,
2956 ssl_version=ssl.PROTOCOL_TLSv1)
2957 s.connect((HOST, server.port))
2958 s.setblocking(False)
2959
2960 # If we keep sending data, at some point the buffers
2961 # will be full and the call will block
2962 buf = bytearray(8192)
2963 def fill_buffer():
2964 while True:
2965 s.send(buf)
2966 self.assertRaises((ssl.SSLWantWriteError,
2967 ssl.SSLWantReadError), fill_buffer)
2968
2969 # Now read all the output and discard it
2970 s.setblocking(True)
2971 s.close()
2972
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002973 def test_handshake_timeout(self):
2974 # Issue #5103: SSL handshake must respect the socket timeout
2975 server = socket.socket(socket.AF_INET)
2976 host = "127.0.0.1"
2977 port = support.bind_port(server)
2978 started = threading.Event()
2979 finish = False
2980
2981 def serve():
Charles-François Natali6e204602014-07-23 19:28:13 +01002982 server.listen()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002983 started.set()
2984 conns = []
2985 while not finish:
2986 r, w, e = select.select([server], [], [], 0.1)
2987 if server in r:
2988 # Let the socket hang around rather than having
2989 # it closed by garbage collection.
2990 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00002991 for sock in conns:
2992 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002993
2994 t = threading.Thread(target=serve)
2995 t.start()
2996 started.wait()
2997
2998 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00002999 try:
3000 c = socket.socket(socket.AF_INET)
3001 c.settimeout(0.2)
3002 c.connect((host, port))
3003 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003004 self.assertRaisesRegex(socket.timeout, "timed out",
Christian Heimesd0486372016-09-10 23:23:33 +02003005 test_wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00003006 finally:
3007 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003008 try:
3009 c = socket.socket(socket.AF_INET)
Christian Heimesd0486372016-09-10 23:23:33 +02003010 c = test_wrap_socket(c)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003011 c.settimeout(0.2)
3012 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00003013 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00003014 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00003015 finally:
3016 c.close()
3017 finally:
3018 finish = True
3019 t.join()
3020 server.close()
3021
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003022 def test_server_accept(self):
3023 # Issue #16357: accept() on a SSLSocket created through
3024 # SSLContext.wrap_socket().
3025 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3026 context.verify_mode = ssl.CERT_REQUIRED
3027 context.load_verify_locations(CERTFILE)
3028 context.load_cert_chain(CERTFILE)
3029 server = socket.socket(socket.AF_INET)
3030 host = "127.0.0.1"
3031 port = support.bind_port(server)
3032 server = context.wrap_socket(server, server_side=True)
Christian Heimesa5d07652016-09-24 10:48:05 +02003033 self.assertTrue(server.server_side)
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003034
3035 evt = threading.Event()
3036 remote = None
3037 peer = None
3038 def serve():
3039 nonlocal remote, peer
Charles-François Natali6e204602014-07-23 19:28:13 +01003040 server.listen()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003041 # Block on the accept and wait on the connection to close.
3042 evt.set()
3043 remote, peer = server.accept()
3044 remote.recv(1)
3045
3046 t = threading.Thread(target=serve)
3047 t.start()
3048 # Client wait until server setup and perform a connect.
3049 evt.wait()
3050 client = context.wrap_socket(socket.socket())
3051 client.connect((host, port))
3052 client_addr = client.getsockname()
3053 client.close()
3054 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003055 remote.close()
3056 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01003057 # Sanity checks.
3058 self.assertIsInstance(remote, ssl.SSLSocket)
3059 self.assertEqual(peer, client_addr)
3060
Antoine Pitrou242db722013-05-01 20:52:07 +02003061 def test_getpeercert_enotconn(self):
3062 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3063 with context.wrap_socket(socket.socket()) as sock:
3064 with self.assertRaises(OSError) as cm:
3065 sock.getpeercert()
3066 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3067
3068 def test_do_handshake_enotconn(self):
3069 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3070 with context.wrap_socket(socket.socket()) as sock:
3071 with self.assertRaises(OSError) as cm:
3072 sock.do_handshake()
3073 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
3074
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003075 def test_default_ciphers(self):
3076 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3077 try:
3078 # Force a set of weak ciphers on our client context
3079 context.set_ciphers("DES")
3080 except ssl.SSLError:
3081 self.skipTest("no DES cipher available")
3082 with ThreadedEchoServer(CERTFILE,
3083 ssl_version=ssl.PROTOCOL_SSLv23,
3084 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003085 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02003086 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003087 s.connect((HOST, server.port))
3088 self.assertIn("no shared cipher", str(server.conn_errors[0]))
3089
Antoine Pitrou47e40422014-09-04 21:00:10 +02003090 def test_version_basic(self):
3091 """
3092 Basic tests for SSLSocket.version().
3093 More tests are done in the test_protocol_*() methods.
3094 """
3095 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3096 with ThreadedEchoServer(CERTFILE,
3097 ssl_version=ssl.PROTOCOL_TLSv1,
3098 chatty=False) as server:
3099 with context.wrap_socket(socket.socket()) as s:
3100 self.assertIs(s.version(), None)
3101 s.connect((HOST, server.port))
Christian Heimes598894f2016-09-05 23:19:05 +02003102 self.assertEqual(s.version(), 'TLSv1')
Antoine Pitrou47e40422014-09-04 21:00:10 +02003103 self.assertIs(s.version(), None)
3104
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003105 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
3106 def test_default_ecdh_curve(self):
3107 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
3108 # should be enabled by default on SSL contexts.
3109 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3110 context.load_cert_chain(CERTFILE)
Antoine Pitrouc0430612014-04-16 18:33:39 +02003111 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
3112 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
3113 # our default cipher list should prefer ECDH-based ciphers
3114 # automatically.
3115 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
3116 context.set_ciphers("ECCdraft:ECDH")
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003117 with ThreadedEchoServer(context=context) as server:
3118 with context.wrap_socket(socket.socket()) as s:
3119 s.connect((HOST, server.port))
3120 self.assertIn("ECDH", s.cipher()[0])
3121
Antoine Pitroud6494802011-07-21 01:11:30 +02003122 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
3123 "'tls-unique' channel binding not available")
3124 def test_tls_unique_channel_binding(self):
3125 """Test tls-unique channel binding."""
3126 if support.verbose:
3127 sys.stdout.write("\n")
3128
3129 server = ThreadedEchoServer(CERTFILE,
3130 certreqs=ssl.CERT_NONE,
3131 ssl_version=ssl.PROTOCOL_TLSv1,
3132 cacerts=CERTFILE,
3133 chatty=True,
3134 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003135 with server:
Christian Heimesd0486372016-09-10 23:23:33 +02003136 s = test_wrap_socket(socket.socket(),
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003137 server_side=False,
3138 certfile=CERTFILE,
3139 ca_certs=CERTFILE,
3140 cert_reqs=ssl.CERT_NONE,
3141 ssl_version=ssl.PROTOCOL_TLSv1)
3142 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02003143 # get the data
3144 cb_data = s.get_channel_binding("tls-unique")
3145 if support.verbose:
3146 sys.stdout.write(" got channel binding data: {0!r}\n"
3147 .format(cb_data))
3148
3149 # check if it is sane
3150 self.assertIsNotNone(cb_data)
3151 self.assertEqual(len(cb_data), 12) # True for TLSv1
3152
3153 # and compare with the peers version
3154 s.write(b"CB tls-unique\n")
3155 peer_data_repr = s.read().strip()
3156 self.assertEqual(peer_data_repr,
3157 repr(cb_data).encode("us-ascii"))
3158 s.close()
3159
3160 # now, again
Christian Heimesd0486372016-09-10 23:23:33 +02003161 s = test_wrap_socket(socket.socket(),
Antoine Pitroud6494802011-07-21 01:11:30 +02003162 server_side=False,
3163 certfile=CERTFILE,
3164 ca_certs=CERTFILE,
3165 cert_reqs=ssl.CERT_NONE,
3166 ssl_version=ssl.PROTOCOL_TLSv1)
3167 s.connect((HOST, server.port))
3168 new_cb_data = s.get_channel_binding("tls-unique")
3169 if support.verbose:
3170 sys.stdout.write(" got another channel binding data: {0!r}\n"
3171 .format(new_cb_data))
3172 # is it really unique
3173 self.assertNotEqual(cb_data, new_cb_data)
3174 self.assertIsNotNone(cb_data)
3175 self.assertEqual(len(cb_data), 12) # True for TLSv1
3176 s.write(b"CB tls-unique\n")
3177 peer_data_repr = s.read().strip()
3178 self.assertEqual(peer_data_repr,
3179 repr(new_cb_data).encode("us-ascii"))
3180 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00003181
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003182 def test_compression(self):
3183 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3184 context.load_cert_chain(CERTFILE)
3185 stats = server_params_test(context, context,
3186 chatty=True, connectionchatty=True)
3187 if support.verbose:
3188 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
3189 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
3190
3191 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
3192 "ssl.OP_NO_COMPRESSION needed for this test")
3193 def test_compression_disabled(self):
3194 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3195 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01003196 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003197 stats = server_params_test(context, context,
3198 chatty=True, connectionchatty=True)
3199 self.assertIs(stats['compression'], None)
3200
Antoine Pitrou0e576f12011-12-22 10:03:38 +01003201 def test_dh_params(self):
3202 # Check we can get a connection with ephemeral Diffie-Hellman
3203 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3204 context.load_cert_chain(CERTFILE)
3205 context.load_dh_params(DHFILE)
3206 context.set_ciphers("kEDH")
3207 stats = server_params_test(context, context,
3208 chatty=True, connectionchatty=True)
3209 cipher = stats["cipher"][0]
3210 parts = cipher.split("-")
3211 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
3212 self.fail("Non-DH cipher: " + cipher[0])
3213
Benjamin Petersoncca27322015-01-23 16:35:37 -05003214 def test_selected_alpn_protocol(self):
3215 # selected_alpn_protocol() is None unless ALPN is used.
3216 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3217 context.load_cert_chain(CERTFILE)
3218 stats = server_params_test(context, context,
3219 chatty=True, connectionchatty=True)
3220 self.assertIs(stats['client_alpn_protocol'], None)
3221
3222 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
3223 def test_selected_alpn_protocol_if_server_uses_alpn(self):
3224 # selected_alpn_protocol() is None unless ALPN is used by the client.
3225 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3226 client_context.load_verify_locations(CERTFILE)
3227 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3228 server_context.load_cert_chain(CERTFILE)
3229 server_context.set_alpn_protocols(['foo', 'bar'])
3230 stats = server_params_test(client_context, server_context,
3231 chatty=True, connectionchatty=True)
3232 self.assertIs(stats['client_alpn_protocol'], None)
3233
3234 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
3235 def test_alpn_protocols(self):
3236 server_protocols = ['foo', 'bar', 'milkshake']
3237 protocol_tests = [
3238 (['foo', 'bar'], 'foo'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003239 (['bar', 'foo'], 'foo'),
Benjamin Petersoncca27322015-01-23 16:35:37 -05003240 (['milkshake'], 'milkshake'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003241 (['http/3.0', 'http/4.0'], None)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003242 ]
3243 for client_protocols, expected in protocol_tests:
Christian Heimes598894f2016-09-05 23:19:05 +02003244 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003245 server_context.load_cert_chain(CERTFILE)
3246 server_context.set_alpn_protocols(server_protocols)
Christian Heimes598894f2016-09-05 23:19:05 +02003247 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003248 client_context.load_cert_chain(CERTFILE)
3249 client_context.set_alpn_protocols(client_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003250
Christian Heimes598894f2016-09-05 23:19:05 +02003251 try:
3252 stats = server_params_test(client_context,
3253 server_context,
3254 chatty=True,
3255 connectionchatty=True)
3256 except ssl.SSLError as e:
3257 stats = e
3258
3259 if expected is None and IS_OPENSSL_1_1:
3260 # OpenSSL 1.1.0 raises handshake error
3261 self.assertIsInstance(stats, ssl.SSLError)
3262 else:
3263 msg = "failed trying %s (s) and %s (c).\n" \
3264 "was expecting %s, but got %%s from the %%s" \
3265 % (str(server_protocols), str(client_protocols),
3266 str(expected))
3267 client_result = stats['client_alpn_protocol']
3268 self.assertEqual(client_result, expected,
3269 msg % (client_result, "client"))
3270 server_result = stats['server_alpn_protocols'][-1] \
3271 if len(stats['server_alpn_protocols']) else 'nothing'
3272 self.assertEqual(server_result, expected,
3273 msg % (server_result, "server"))
Benjamin Petersoncca27322015-01-23 16:35:37 -05003274
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01003275 def test_selected_npn_protocol(self):
3276 # selected_npn_protocol() is None unless NPN is used
3277 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3278 context.load_cert_chain(CERTFILE)
3279 stats = server_params_test(context, context,
3280 chatty=True, connectionchatty=True)
3281 self.assertIs(stats['client_npn_protocol'], None)
3282
3283 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
3284 def test_npn_protocols(self):
3285 server_protocols = ['http/1.1', 'spdy/2']
3286 protocol_tests = [
3287 (['http/1.1', 'spdy/2'], 'http/1.1'),
3288 (['spdy/2', 'http/1.1'], 'http/1.1'),
3289 (['spdy/2', 'test'], 'spdy/2'),
3290 (['abc', 'def'], 'abc')
3291 ]
3292 for client_protocols, expected in protocol_tests:
3293 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3294 server_context.load_cert_chain(CERTFILE)
3295 server_context.set_npn_protocols(server_protocols)
3296 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3297 client_context.load_cert_chain(CERTFILE)
3298 client_context.set_npn_protocols(client_protocols)
3299 stats = server_params_test(client_context, server_context,
3300 chatty=True, connectionchatty=True)
3301
3302 msg = "failed trying %s (s) and %s (c).\n" \
3303 "was expecting %s, but got %%s from the %%s" \
3304 % (str(server_protocols), str(client_protocols),
3305 str(expected))
3306 client_result = stats['client_npn_protocol']
3307 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3308 server_result = stats['server_npn_protocols'][-1] \
3309 if len(stats['server_npn_protocols']) else 'nothing'
3310 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3311
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003312 def sni_contexts(self):
3313 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3314 server_context.load_cert_chain(SIGNED_CERTFILE)
3315 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3316 other_context.load_cert_chain(SIGNED_CERTFILE2)
3317 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3318 client_context.verify_mode = ssl.CERT_REQUIRED
3319 client_context.load_verify_locations(SIGNING_CA)
3320 return server_context, other_context, client_context
3321
3322 def check_common_name(self, stats, name):
3323 cert = stats['peercert']
3324 self.assertIn((('commonName', name),), cert['subject'])
3325
3326 @needs_sni
3327 def test_sni_callback(self):
3328 calls = []
3329 server_context, other_context, client_context = self.sni_contexts()
3330
3331 def servername_cb(ssl_sock, server_name, initial_context):
3332 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003333 if server_name is not None:
3334 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003335 server_context.set_servername_callback(servername_cb)
3336
3337 stats = server_params_test(client_context, server_context,
3338 chatty=True,
3339 sni_name='supermessage')
3340 # The hostname was fetched properly, and the certificate was
3341 # changed for the connection.
3342 self.assertEqual(calls, [("supermessage", server_context)])
3343 # CERTFILE4 was selected
3344 self.check_common_name(stats, 'fakehostname')
3345
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003346 calls = []
3347 # The callback is called with server_name=None
3348 stats = server_params_test(client_context, server_context,
3349 chatty=True,
3350 sni_name=None)
3351 self.assertEqual(calls, [(None, server_context)])
3352 self.check_common_name(stats, 'localhost')
3353
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003354 # Check disabling the callback
3355 calls = []
3356 server_context.set_servername_callback(None)
3357
3358 stats = server_params_test(client_context, server_context,
3359 chatty=True,
3360 sni_name='notfunny')
3361 # Certificate didn't change
3362 self.check_common_name(stats, 'localhost')
3363 self.assertEqual(calls, [])
3364
3365 @needs_sni
3366 def test_sni_callback_alert(self):
3367 # Returning a TLS alert is reflected to the connecting client
3368 server_context, other_context, client_context = self.sni_contexts()
3369
3370 def cb_returning_alert(ssl_sock, server_name, initial_context):
3371 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3372 server_context.set_servername_callback(cb_returning_alert)
3373
3374 with self.assertRaises(ssl.SSLError) as cm:
3375 stats = server_params_test(client_context, server_context,
3376 chatty=False,
3377 sni_name='supermessage')
3378 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3379
3380 @needs_sni
3381 def test_sni_callback_raising(self):
3382 # Raising fails the connection with a TLS handshake failure alert.
3383 server_context, other_context, client_context = self.sni_contexts()
3384
3385 def cb_raising(ssl_sock, server_name, initial_context):
3386 1/0
3387 server_context.set_servername_callback(cb_raising)
3388
3389 with self.assertRaises(ssl.SSLError) as cm, \
3390 support.captured_stderr() as stderr:
3391 stats = server_params_test(client_context, server_context,
3392 chatty=False,
3393 sni_name='supermessage')
3394 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3395 self.assertIn("ZeroDivisionError", stderr.getvalue())
3396
3397 @needs_sni
3398 def test_sni_callback_wrong_return_type(self):
3399 # Returning the wrong return type terminates the TLS connection
3400 # with an internal error alert.
3401 server_context, other_context, client_context = self.sni_contexts()
3402
3403 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3404 return "foo"
3405 server_context.set_servername_callback(cb_wrong_return_type)
3406
3407 with self.assertRaises(ssl.SSLError) as cm, \
3408 support.captured_stderr() as stderr:
3409 stats = server_params_test(client_context, server_context,
3410 chatty=False,
3411 sni_name='supermessage')
3412 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3413 self.assertIn("TypeError", stderr.getvalue())
3414
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003415 def test_shared_ciphers(self):
Benjamin Petersonaacd5242015-01-07 11:42:38 -06003416 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson15042922015-01-07 22:12:43 -06003417 server_context.load_cert_chain(SIGNED_CERTFILE)
3418 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3419 client_context.verify_mode = ssl.CERT_REQUIRED
3420 client_context.load_verify_locations(SIGNING_CA)
Christian Heimes598894f2016-09-05 23:19:05 +02003421 if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
3422 client_context.set_ciphers("AES128:AES256")
3423 server_context.set_ciphers("AES256")
3424 alg1 = "AES256"
3425 alg2 = "AES-256"
3426 else:
3427 client_context.set_ciphers("AES:3DES")
3428 server_context.set_ciphers("3DES")
3429 alg1 = "3DES"
3430 alg2 = "DES-CBC3"
3431
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003432 stats = server_params_test(client_context, server_context)
3433 ciphers = stats['server_shared_ciphers'][0]
3434 self.assertGreater(len(ciphers), 0)
3435 for name, tls_version, bits in ciphers:
Christian Heimes598894f2016-09-05 23:19:05 +02003436 if not alg1 in name.split("-") and alg2 not in name:
3437 self.fail(name)
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003438
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003439 def test_read_write_after_close_raises_valuerror(self):
3440 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3441 context.verify_mode = ssl.CERT_REQUIRED
3442 context.load_verify_locations(CERTFILE)
3443 context.load_cert_chain(CERTFILE)
3444 server = ThreadedEchoServer(context=context, chatty=False)
3445
3446 with server:
3447 s = context.wrap_socket(socket.socket())
3448 s.connect((HOST, server.port))
3449 s.close()
3450
3451 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02003452 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003453
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02003454 def test_sendfile(self):
3455 TEST_DATA = b"x" * 512
3456 with open(support.TESTFN, 'wb') as f:
3457 f.write(TEST_DATA)
3458 self.addCleanup(support.unlink, support.TESTFN)
3459 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3460 context.verify_mode = ssl.CERT_REQUIRED
3461 context.load_verify_locations(CERTFILE)
3462 context.load_cert_chain(CERTFILE)
3463 server = ThreadedEchoServer(context=context, chatty=False)
3464 with server:
3465 with context.wrap_socket(socket.socket()) as s:
3466 s.connect((HOST, server.port))
3467 with open(support.TESTFN, 'rb') as file:
3468 s.sendfile(file)
3469 self.assertEqual(s.recv(1024), TEST_DATA)
3470
Christian Heimes99a65702016-09-10 23:44:53 +02003471 def test_session(self):
3472 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3473 server_context.load_cert_chain(SIGNED_CERTFILE)
3474 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3475 client_context.verify_mode = ssl.CERT_REQUIRED
3476 client_context.load_verify_locations(SIGNING_CA)
3477
Martin Panterb1321fb2016-10-10 00:38:21 +00003478 # first connection without session
Christian Heimes99a65702016-09-10 23:44:53 +02003479 stats = server_params_test(client_context, server_context)
3480 session = stats['session']
3481 self.assertTrue(session.id)
3482 self.assertGreater(session.time, 0)
3483 self.assertGreater(session.timeout, 0)
3484 self.assertTrue(session.has_ticket)
3485 if ssl.OPENSSL_VERSION_INFO > (1, 0, 1):
3486 self.assertGreater(session.ticket_lifetime_hint, 0)
3487 self.assertFalse(stats['session_reused'])
3488 sess_stat = server_context.session_stats()
3489 self.assertEqual(sess_stat['accept'], 1)
3490 self.assertEqual(sess_stat['hits'], 0)
3491
3492 # reuse session
3493 stats = server_params_test(client_context, server_context, session=session)
3494 sess_stat = server_context.session_stats()
3495 self.assertEqual(sess_stat['accept'], 2)
3496 self.assertEqual(sess_stat['hits'], 1)
3497 self.assertTrue(stats['session_reused'])
3498 session2 = stats['session']
3499 self.assertEqual(session2.id, session.id)
3500 self.assertEqual(session2, session)
3501 self.assertIsNot(session2, session)
3502 self.assertGreaterEqual(session2.time, session.time)
3503 self.assertGreaterEqual(session2.timeout, session.timeout)
3504
3505 # another one without session
3506 stats = server_params_test(client_context, server_context)
3507 self.assertFalse(stats['session_reused'])
3508 session3 = stats['session']
3509 self.assertNotEqual(session3.id, session.id)
3510 self.assertNotEqual(session3, session)
3511 sess_stat = server_context.session_stats()
3512 self.assertEqual(sess_stat['accept'], 3)
3513 self.assertEqual(sess_stat['hits'], 1)
3514
3515 # reuse session again
3516 stats = server_params_test(client_context, server_context, session=session)
3517 self.assertTrue(stats['session_reused'])
3518 session4 = stats['session']
3519 self.assertEqual(session4.id, session.id)
3520 self.assertEqual(session4, session)
3521 self.assertGreaterEqual(session4.time, session.time)
3522 self.assertGreaterEqual(session4.timeout, session.timeout)
3523 sess_stat = server_context.session_stats()
3524 self.assertEqual(sess_stat['accept'], 4)
3525 self.assertEqual(sess_stat['hits'], 2)
3526
3527 def test_session_handling(self):
3528 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3529 context.verify_mode = ssl.CERT_REQUIRED
3530 context.load_verify_locations(CERTFILE)
3531 context.load_cert_chain(CERTFILE)
3532
3533 context2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3534 context2.verify_mode = ssl.CERT_REQUIRED
3535 context2.load_verify_locations(CERTFILE)
3536 context2.load_cert_chain(CERTFILE)
3537
3538 server = ThreadedEchoServer(context=context, chatty=False)
3539 with server:
3540 with context.wrap_socket(socket.socket()) as s:
3541 # session is None before handshake
3542 self.assertEqual(s.session, None)
3543 self.assertEqual(s.session_reused, None)
3544 s.connect((HOST, server.port))
3545 session = s.session
3546 self.assertTrue(session)
3547 with self.assertRaises(TypeError) as e:
3548 s.session = object
3549 self.assertEqual(str(e.exception), 'Value is not a SSLSession.')
3550
3551 with context.wrap_socket(socket.socket()) as s:
3552 s.connect((HOST, server.port))
3553 # cannot set session after handshake
3554 with self.assertRaises(ValueError) as e:
3555 s.session = session
3556 self.assertEqual(str(e.exception),
3557 'Cannot set session after handshake.')
3558
3559 with context.wrap_socket(socket.socket()) as s:
3560 # can set session before handshake and before the
3561 # connection was established
3562 s.session = session
3563 s.connect((HOST, server.port))
3564 self.assertEqual(s.session.id, session.id)
3565 self.assertEqual(s.session, session)
3566 self.assertEqual(s.session_reused, True)
3567
3568 with context2.wrap_socket(socket.socket()) as s:
3569 # cannot re-use session with a different SSLContext
3570 with self.assertRaises(ValueError) as e:
3571 s.session = session
3572 s.connect((HOST, server.port))
3573 self.assertEqual(str(e.exception),
3574 'Session refers to a different SSLContext.')
3575
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003576
Thomas Woutersed03b412007-08-28 21:37:11 +00003577def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00003578 if support.verbose:
Berker Peksag9e7990a2015-05-16 23:21:26 +03003579 import warnings
Antoine Pitrou15cee622010-08-04 16:45:21 +00003580 plats = {
3581 'Linux': platform.linux_distribution,
3582 'Mac': platform.mac_ver,
3583 'Windows': platform.win32_ver,
3584 }
Berker Peksag9e7990a2015-05-16 23:21:26 +03003585 with warnings.catch_warnings():
3586 warnings.filterwarnings(
3587 'ignore',
R David Murray44b548d2016-09-08 13:59:53 -04003588 r'dist\(\) and linux_distribution\(\) '
Berker Peksag9e7990a2015-05-16 23:21:26 +03003589 'functions are deprecated .*',
3590 PendingDeprecationWarning,
3591 )
3592 for name, func in plats.items():
3593 plat = func()
3594 if plat and plat[0]:
3595 plat = '%s %r' % (name, plat)
3596 break
3597 else:
3598 plat = repr(platform.platform())
Antoine Pitrou15cee622010-08-04 16:45:21 +00003599 print("test_ssl: testing with %r %r" %
3600 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3601 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00003602 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01003603 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3604 try:
3605 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3606 except AttributeError:
3607 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00003608
Antoine Pitrou152efa22010-05-16 18:19:27 +00003609 for filename in [
Martin Panter3840b2a2016-03-27 01:53:46 +00003610 CERTFILE, BYTES_CERTFILE,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003611 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003612 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003613 BADCERT, BADKEY, EMPTYCERT]:
3614 if not os.path.exists(filename):
3615 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003616
Martin Panter3840b2a2016-03-27 01:53:46 +00003617 tests = [
3618 ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests,
3619 SimpleBackgroundTests,
3620 ]
Thomas Woutersed03b412007-08-28 21:37:11 +00003621
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003622 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00003623 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003624
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003625 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003626 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01003627 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00003628 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003629
Antoine Pitrou480a1242010-04-28 21:37:09 +00003630 try:
3631 support.run_unittest(*tests)
3632 finally:
3633 if _have_threads:
3634 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00003635
3636if __name__ == "__main__":
3637 test_main()