blob: 0f4faa09bdeb676502dd03f10c5446b6a0cf9c02 [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00005from test import support
Thomas Woutersed03b412007-08-28 21:37:11 +00006import socket
Bill Janssen6e027db2007-11-15 22:23:56 +00007import select
Thomas Woutersed03b412007-08-28 21:37:11 +00008import time
Christian Heimes9424bb42013-06-17 15:32:57 +02009import datetime
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000010import gc
Thomas Woutersed03b412007-08-28 21:37:11 +000011import os
Antoine Pitroucfcd8ad2010-04-23 23:31:47 +000012import errno
Thomas Woutersed03b412007-08-28 21:37:11 +000013import pprint
Antoine Pitrou152efa22010-05-16 18:19:27 +000014import tempfile
Antoine Pitrou803e6d62010-10-13 10:36:15 +000015import urllib.request
Thomas Woutersed03b412007-08-28 21:37:11 +000016import traceback
Bill Janssen54cc54c2007-12-14 22:08:56 +000017import asyncore
Antoine Pitrou9d543662010-04-23 23:10:32 +000018import weakref
Antoine Pitrou15cee622010-08-04 16:45:21 +000019import platform
Antoine Pitrou23df4832010-08-04 17:14:06 +000020import functools
Thomas Woutersed03b412007-08-28 21:37:11 +000021
Antoine Pitrou05d936d2010-10-13 11:38:36 +000022ssl = support.import_module("ssl")
23
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010024PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000025HOST = support.HOST
Christian Heimes598894f2016-09-05 23:19:05 +020026IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
27IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
28
Antoine Pitrou152efa22010-05-16 18:19:27 +000029
Christian Heimesefff7062013-11-21 03:35:02 +010030def data_file(*name):
31 return os.path.join(os.path.dirname(__file__), *name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000032
Antoine Pitrou81564092010-10-08 23:06:24 +000033# The custom key and certificate files used in test_ssl are generated
34# using Lib/test/make_ssl_certs.py.
35# Other certificates are simply fetched from the Internet servers they
36# are meant to authenticate.
37
Antoine Pitrou152efa22010-05-16 18:19:27 +000038CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000039BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000040ONLYCERT = data_file("ssl_cert.pem")
41ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000042BYTES_ONLYCERT = os.fsencode(ONLYCERT)
43BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +020044CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
45ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
46KEY_PASSWORD = "somepass"
Antoine Pitrou152efa22010-05-16 18:19:27 +000047CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000048BYTES_CAPATH = os.fsencode(CAPATH)
Christian Heimesefff7062013-11-21 03:35:02 +010049CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
50CAFILE_CACERT = data_file("capath", "5ed36f99.0")
51
Antoine Pitrou152efa22010-05-16 18:19:27 +000052
Christian Heimes22587792013-11-21 23:56:13 +010053# empty CRL
54CRLFILE = data_file("revocation.crl")
55
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010056# Two keys and certs signed by the same CA (for SNI tests)
57SIGNED_CERTFILE = data_file("keycert3.pem")
58SIGNED_CERTFILE2 = data_file("keycert4.pem")
59SIGNING_CA = data_file("pycacert.pem")
Christian Heimes1c03abd2016-09-06 23:25:35 +020060# cert with all kinds of subject alt names
61ALLSANFILE = data_file("allsans.pem")
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010062
Martin Panter3d81d932016-01-14 09:36:00 +000063REMOTE_HOST = "self-signed.pythontest.net"
64REMOTE_ROOT_CERT = data_file("selfsigned_pythontestdotnet.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000065
66EMPTYCERT = data_file("nullcert.pem")
67BADCERT = data_file("badcert.pem")
Martin Panter407b62f2016-01-30 03:41:43 +000068NONEXISTINGCERT = data_file("XXXnonexisting.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000069BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020070NOKIACERT = data_file("nokia.pem")
Christian Heimes824f7f32013-08-17 00:54:47 +020071NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000072
Benjamin Petersona7eaf562015-04-02 00:04:06 -040073DHFILE = data_file("dh1024.pem")
Antoine Pitrou0e576f12011-12-22 10:03:38 +010074BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000075
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010076
Thomas Woutersed03b412007-08-28 21:37:11 +000077def handle_error(prefix):
78 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000079 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000080 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000081
Antoine Pitroub5218772010-05-21 09:56:06 +000082def can_clear_options():
83 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020084 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000085
86def no_sslv2_implies_sslv3_hello():
87 # 0.9.7h or higher
88 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
89
Christian Heimes2427b502013-11-23 11:24:32 +010090def have_verify_flags():
91 # 0.9.8 or higher
92 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
93
Antoine Pitrouc695c952014-04-28 20:57:36 +020094def utc_offset(): #NOTE: ignore issues like #1647654
95 # local time = utc time + utc offset
96 if time.daylight and time.localtime().tm_isdst > 0:
97 return -time.altzone # seconds
98 return -time.timezone
99
Christian Heimes9424bb42013-06-17 15:32:57 +0200100def asn1time(cert_time):
101 # Some versions of OpenSSL ignore seconds, see #18207
102 # 0.9.8.i
103 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
104 fmt = "%b %d %H:%M:%S %Y GMT"
105 dt = datetime.datetime.strptime(cert_time, fmt)
106 dt = dt.replace(second=0)
107 cert_time = dt.strftime(fmt)
108 # %d adds leading zero but ASN1_TIME_print() uses leading space
109 if cert_time[4] == "0":
110 cert_time = cert_time[:4] + " " + cert_time[5:]
111
112 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +0000113
Antoine Pitrou23df4832010-08-04 17:14:06 +0000114# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
115def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +0200116 if hasattr(ssl, 'PROTOCOL_SSLv2'):
117 @functools.wraps(func)
118 def f(*args, **kwargs):
119 try:
120 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
121 except ssl.SSLError:
122 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
123 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
124 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
125 return func(*args, **kwargs)
126 return f
127 else:
128 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000129
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100130needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
131
Antoine Pitrou23df4832010-08-04 17:14:06 +0000132
Antoine Pitrou152efa22010-05-16 18:19:27 +0000133class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000134
Antoine Pitrou480a1242010-04-28 21:37:09 +0000135 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000136 ssl.CERT_NONE
137 ssl.CERT_OPTIONAL
138 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100139 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100140 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100141 if ssl.HAS_ECDH:
142 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100143 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
144 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000145 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100146 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000147
Antoine Pitrou172f0252014-04-18 20:33:08 +0200148 def test_str_for_enums(self):
149 # Make sure that the PROTOCOL_* constants have enum-like string
150 # reprs.
Christian Heimes598894f2016-09-05 23:19:05 +0200151 proto = ssl.PROTOCOL_TLS
152 self.assertEqual(str(proto), '_SSLMethod.PROTOCOL_TLS')
Antoine Pitrou172f0252014-04-18 20:33:08 +0200153 ctx = ssl.SSLContext(proto)
154 self.assertIs(ctx.protocol, proto)
155
Antoine Pitrou480a1242010-04-28 21:37:09 +0000156 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000157 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000158 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000159 sys.stdout.write("\n RAND_status is %d (%s)\n"
160 % (v, (v and "sufficient randomness") or
161 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200162
163 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
164 self.assertEqual(len(data), 16)
165 self.assertEqual(is_cryptographic, v == 1)
166 if v:
167 data = ssl.RAND_bytes(16)
168 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200169 else:
170 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200171
Victor Stinner1e81a392013-12-19 16:47:04 +0100172 # negative num is invalid
173 self.assertRaises(ValueError, ssl.RAND_bytes, -5)
174 self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5)
175
Victor Stinnerbeeb5122014-11-28 13:28:25 +0100176 if hasattr(ssl, 'RAND_egd'):
177 self.assertRaises(TypeError, ssl.RAND_egd, 1)
178 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000179 ssl.RAND_add("this is a random string", 75.0)
Serhiy Storchaka8490f5a2015-03-20 09:00:36 +0200180 ssl.RAND_add(b"this is a random bytes object", 75.0)
181 ssl.RAND_add(bytearray(b"this is a random bytearray object"), 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000182
Christian Heimesf77b4b22013-08-21 13:26:05 +0200183 @unittest.skipUnless(os.name == 'posix', 'requires posix')
184 def test_random_fork(self):
185 status = ssl.RAND_status()
186 if not status:
187 self.fail("OpenSSL's PRNG has insufficient randomness")
188
189 rfd, wfd = os.pipe()
190 pid = os.fork()
191 if pid == 0:
192 try:
193 os.close(rfd)
194 child_random = ssl.RAND_pseudo_bytes(16)[0]
195 self.assertEqual(len(child_random), 16)
196 os.write(wfd, child_random)
197 os.close(wfd)
198 except BaseException:
199 os._exit(1)
200 else:
201 os._exit(0)
202 else:
203 os.close(wfd)
204 self.addCleanup(os.close, rfd)
205 _, status = os.waitpid(pid, 0)
206 self.assertEqual(status, 0)
207
208 child_random = os.read(rfd, 16)
209 self.assertEqual(len(child_random), 16)
210 parent_random = ssl.RAND_pseudo_bytes(16)[0]
211 self.assertEqual(len(parent_random), 16)
212
213 self.assertNotEqual(child_random, parent_random)
214
Antoine Pitrou480a1242010-04-28 21:37:09 +0000215 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000216 # note that this uses an 'unofficial' function in _ssl.c,
217 # provided solely for this test, to exercise the certificate
218 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000219 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000220 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000221 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200222 self.assertEqual(p['issuer'],
223 ((('countryName', 'XY'),),
224 (('localityName', 'Castle Anthrax'),),
225 (('organizationName', 'Python Software Foundation'),),
226 (('commonName', 'localhost'),))
227 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100228 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200229 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
230 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200231 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
232 self.assertEqual(p['subject'],
233 ((('countryName', 'XY'),),
234 (('localityName', 'Castle Anthrax'),),
235 (('organizationName', 'Python Software Foundation'),),
236 (('commonName', 'localhost'),))
237 )
238 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
239 # Issue #13034: the subjectAltName in some certificates
240 # (notably projects.developer.nokia.com:443) wasn't parsed
241 p = ssl._ssl._test_decode_cert(NOKIACERT)
242 if support.verbose:
243 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
244 self.assertEqual(p['subjectAltName'],
245 (('DNS', 'projects.developer.nokia.com'),
246 ('DNS', 'projects.forum.nokia.com'))
247 )
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100248 # extra OCSP and AIA fields
249 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
250 self.assertEqual(p['caIssuers'],
251 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
252 self.assertEqual(p['crlDistributionPoints'],
253 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Thomas Woutersed03b412007-08-28 21:37:11 +0000254
Christian Heimes824f7f32013-08-17 00:54:47 +0200255 def test_parse_cert_CVE_2013_4238(self):
256 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
257 if support.verbose:
258 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
259 subject = ((('countryName', 'US'),),
260 (('stateOrProvinceName', 'Oregon'),),
261 (('localityName', 'Beaverton'),),
262 (('organizationName', 'Python Software Foundation'),),
263 (('organizationalUnitName', 'Python Core Development'),),
264 (('commonName', 'null.python.org\x00example.org'),),
265 (('emailAddress', 'python-dev@python.org'),))
266 self.assertEqual(p['subject'], subject)
267 self.assertEqual(p['issuer'], subject)
Christian Heimes157c9832013-08-25 14:12:41 +0200268 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
269 san = (('DNS', 'altnull.python.org\x00example.com'),
270 ('email', 'null@python.org\x00user@example.org'),
271 ('URI', 'http://null.python.org\x00http://example.org'),
272 ('IP Address', '192.0.2.1'),
273 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
274 else:
275 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
276 san = (('DNS', 'altnull.python.org\x00example.com'),
277 ('email', 'null@python.org\x00user@example.org'),
278 ('URI', 'http://null.python.org\x00http://example.org'),
279 ('IP Address', '192.0.2.1'),
280 ('IP Address', '<invalid>'))
281
282 self.assertEqual(p['subjectAltName'], san)
Christian Heimes824f7f32013-08-17 00:54:47 +0200283
Christian Heimes1c03abd2016-09-06 23:25:35 +0200284 def test_parse_all_sans(self):
285 p = ssl._ssl._test_decode_cert(ALLSANFILE)
286 self.assertEqual(p['subjectAltName'],
287 (
288 ('DNS', 'allsans'),
289 ('othername', '<unsupported>'),
290 ('othername', '<unsupported>'),
291 ('email', 'user@example.org'),
292 ('DNS', 'www.example.org'),
293 ('DirName',
294 ((('countryName', 'XY'),),
295 (('localityName', 'Castle Anthrax'),),
296 (('organizationName', 'Python Software Foundation'),),
297 (('commonName', 'dirname example'),))),
298 ('URI', 'https://www.python.org/'),
299 ('IP Address', '127.0.0.1'),
300 ('IP Address', '0:0:0:0:0:0:0:1\n'),
301 ('Registered ID', '1.2.3.4.5')
302 )
303 )
304
Antoine Pitrou480a1242010-04-28 21:37:09 +0000305 def test_DER_to_PEM(self):
Martin Panter3d81d932016-01-14 09:36:00 +0000306 with open(CAFILE_CACERT, 'r') as f:
Antoine Pitrou480a1242010-04-28 21:37:09 +0000307 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000308 d1 = ssl.PEM_cert_to_DER_cert(pem)
309 p2 = ssl.DER_cert_to_PEM_cert(d1)
310 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000311 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000312 if not p2.startswith(ssl.PEM_HEADER + '\n'):
313 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
314 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
315 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000316
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000317 def test_openssl_version(self):
318 n = ssl.OPENSSL_VERSION_NUMBER
319 t = ssl.OPENSSL_VERSION_INFO
320 s = ssl.OPENSSL_VERSION
321 self.assertIsInstance(n, int)
322 self.assertIsInstance(t, tuple)
323 self.assertIsInstance(s, str)
324 # Some sanity checks follow
325 # >= 0.9
326 self.assertGreaterEqual(n, 0x900000)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400327 # < 3.0
328 self.assertLess(n, 0x30000000)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000329 major, minor, fix, patch, status = t
330 self.assertGreaterEqual(major, 0)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400331 self.assertLess(major, 3)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000332 self.assertGreaterEqual(minor, 0)
333 self.assertLess(minor, 256)
334 self.assertGreaterEqual(fix, 0)
335 self.assertLess(fix, 256)
336 self.assertGreaterEqual(patch, 0)
Ned Deily05784a72015-02-05 17:20:13 +1100337 self.assertLessEqual(patch, 63)
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000338 self.assertGreaterEqual(status, 0)
339 self.assertLessEqual(status, 15)
Antoine Pitroudfab9352014-07-21 18:35:01 -0400340 # Version string as returned by {Open,Libre}SSL, the format might change
Christian Heimes598894f2016-09-05 23:19:05 +0200341 if IS_LIBRESSL:
342 self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
Victor Stinner789b8052015-01-06 11:51:06 +0100343 (s, t, hex(n)))
Antoine Pitroudfab9352014-07-21 18:35:01 -0400344 else:
345 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
Victor Stinner789b8052015-01-06 11:51:06 +0100346 (s, t, hex(n)))
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000347
Antoine Pitrou9d543662010-04-23 23:10:32 +0000348 @support.cpython_only
349 def test_refcycle(self):
350 # Issue #7943: an SSL object doesn't create reference cycles with
351 # itself.
352 s = socket.socket(socket.AF_INET)
353 ss = ssl.wrap_socket(s)
354 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100355 with support.check_warnings(("", ResourceWarning)):
356 del ss
357 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000358
Antoine Pitroua468adc2010-09-14 14:43:44 +0000359 def test_wrapped_unconnected(self):
360 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200361 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000362 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100363 with ssl.wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100364 self.assertRaises(OSError, ss.recv, 1)
365 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
366 self.assertRaises(OSError, ss.recvfrom, 1)
367 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
368 self.assertRaises(OSError, ss.send, b'x')
369 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000370
Antoine Pitrou40f08742010-04-24 22:04:40 +0000371 def test_timeout(self):
372 # Issue #8524: when creating an SSL socket, the timeout of the
373 # original socket should be retained.
374 for timeout in (None, 0.0, 5.0):
375 s = socket.socket(socket.AF_INET)
376 s.settimeout(timeout)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100377 with ssl.wrap_socket(s) as ss:
378 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000379
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000380 def test_errors(self):
381 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000382 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000383 "certfile must be specified",
384 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000385 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000386 "certfile must be specified for server-side operations",
387 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000388 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000389 "certfile must be specified for server-side operations",
390 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100391 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
392 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
393 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200394 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000395 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000396 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000397 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200398 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000399 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000400 ssl.wrap_socket(sock,
401 certfile=CERTFILE, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000402 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200403 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000404 with socket.socket() as sock:
Martin Panter407b62f2016-01-30 03:41:43 +0000405 ssl.wrap_socket(sock,
406 certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000407 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000408
Martin Panter3464ea22016-02-01 21:58:11 +0000409 def bad_cert_test(self, certfile):
410 """Check that trying to use the given client certificate fails"""
411 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
412 certfile)
413 sock = socket.socket()
414 self.addCleanup(sock.close)
415 with self.assertRaises(ssl.SSLError):
416 ssl.wrap_socket(sock,
417 certfile=certfile,
418 ssl_version=ssl.PROTOCOL_TLSv1)
419
420 def test_empty_cert(self):
421 """Wrapping with an empty cert file"""
422 self.bad_cert_test("nullcert.pem")
423
424 def test_malformed_cert(self):
425 """Wrapping with a badly formatted certificate (syntax error)"""
426 self.bad_cert_test("badcert.pem")
427
428 def test_malformed_key(self):
429 """Wrapping with a badly formatted key (syntax error)"""
430 self.bad_cert_test("badkey.pem")
431
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000432 def test_match_hostname(self):
433 def ok(cert, hostname):
434 ssl.match_hostname(cert, hostname)
435 def fail(cert, hostname):
436 self.assertRaises(ssl.CertificateError,
437 ssl.match_hostname, cert, hostname)
438
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100439 # -- Hostname matching --
440
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000441 cert = {'subject': ((('commonName', 'example.com'),),)}
442 ok(cert, 'example.com')
443 ok(cert, 'ExAmple.cOm')
444 fail(cert, 'www.example.com')
445 fail(cert, '.example.com')
446 fail(cert, 'example.org')
447 fail(cert, 'exampleXcom')
448
449 cert = {'subject': ((('commonName', '*.a.com'),),)}
450 ok(cert, 'foo.a.com')
451 fail(cert, 'bar.foo.a.com')
452 fail(cert, 'a.com')
453 fail(cert, 'Xa.com')
454 fail(cert, '.a.com')
455
Georg Brandl72c98d32013-10-27 07:16:53 +0100456 # only match one left-most wildcard
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000457 cert = {'subject': ((('commonName', 'f*.com'),),)}
458 ok(cert, 'foo.com')
459 ok(cert, 'f.com')
460 fail(cert, 'bar.com')
461 fail(cert, 'foo.a.com')
462 fail(cert, 'bar.foo.com')
463
Christian Heimes824f7f32013-08-17 00:54:47 +0200464 # NULL bytes are bad, CVE-2013-4073
465 cert = {'subject': ((('commonName',
466 'null.python.org\x00example.org'),),)}
467 ok(cert, 'null.python.org\x00example.org') # or raise an error?
468 fail(cert, 'example.org')
469 fail(cert, 'null.python.org')
470
Georg Brandl72c98d32013-10-27 07:16:53 +0100471 # error cases with wildcards
472 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
473 fail(cert, 'bar.foo.a.com')
474 fail(cert, 'a.com')
475 fail(cert, 'Xa.com')
476 fail(cert, '.a.com')
477
478 cert = {'subject': ((('commonName', 'a.*.com'),),)}
479 fail(cert, 'a.foo.com')
480 fail(cert, 'a..com')
481 fail(cert, 'a.com')
482
483 # wildcard doesn't match IDNA prefix 'xn--'
484 idna = 'püthon.python.org'.encode("idna").decode("ascii")
485 cert = {'subject': ((('commonName', idna),),)}
486 ok(cert, idna)
487 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
488 fail(cert, idna)
489 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
490 fail(cert, idna)
491
492 # wildcard in first fragment and IDNA A-labels in sequent fragments
493 # are supported.
494 idna = 'www*.pythön.org'.encode("idna").decode("ascii")
495 cert = {'subject': ((('commonName', idna),),)}
496 ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
497 ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
498 fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
499 fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
500
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000501 # Slightly fake real-world example
502 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
503 'subject': ((('commonName', 'linuxfrz.org'),),),
504 'subjectAltName': (('DNS', 'linuxfr.org'),
505 ('DNS', 'linuxfr.com'),
506 ('othername', '<unsupported>'))}
507 ok(cert, 'linuxfr.org')
508 ok(cert, 'linuxfr.com')
509 # Not a "DNS" entry
510 fail(cert, '<unsupported>')
511 # When there is a subjectAltName, commonName isn't used
512 fail(cert, 'linuxfrz.org')
513
514 # A pristine real-world example
515 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
516 'subject': ((('countryName', 'US'),),
517 (('stateOrProvinceName', 'California'),),
518 (('localityName', 'Mountain View'),),
519 (('organizationName', 'Google Inc'),),
520 (('commonName', 'mail.google.com'),))}
521 ok(cert, 'mail.google.com')
522 fail(cert, 'gmail.com')
523 # Only commonName is considered
524 fail(cert, 'California')
525
Antoine Pitrouc481bfb2015-02-15 18:12:20 +0100526 # -- IPv4 matching --
527 cert = {'subject': ((('commonName', 'example.com'),),),
528 'subjectAltName': (('DNS', 'example.com'),
529 ('IP Address', '10.11.12.13'),
530 ('IP Address', '14.15.16.17'))}
531 ok(cert, '10.11.12.13')
532 ok(cert, '14.15.16.17')
533 fail(cert, '14.15.16.18')
534 fail(cert, 'example.net')
535
536 # -- IPv6 matching --
537 cert = {'subject': ((('commonName', 'example.com'),),),
538 'subjectAltName': (('DNS', 'example.com'),
539 ('IP Address', '2001:0:0:0:0:0:0:CAFE\n'),
540 ('IP Address', '2003:0:0:0:0:0:0:BABA\n'))}
541 ok(cert, '2001::cafe')
542 ok(cert, '2003::baba')
543 fail(cert, '2003::bebe')
544 fail(cert, 'example.net')
545
546 # -- Miscellaneous --
547
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000548 # Neither commonName nor subjectAltName
549 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
550 'subject': ((('countryName', 'US'),),
551 (('stateOrProvinceName', 'California'),),
552 (('localityName', 'Mountain View'),),
553 (('organizationName', 'Google Inc'),))}
554 fail(cert, 'mail.google.com')
555
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200556 # No DNS entry in subjectAltName but a commonName
557 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
558 'subject': ((('countryName', 'US'),),
559 (('stateOrProvinceName', 'California'),),
560 (('localityName', 'Mountain View'),),
561 (('commonName', 'mail.google.com'),)),
562 'subjectAltName': (('othername', 'blabla'), )}
563 ok(cert, 'mail.google.com')
564
565 # No DNS entry subjectAltName and no commonName
566 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
567 'subject': ((('countryName', 'US'),),
568 (('stateOrProvinceName', 'California'),),
569 (('localityName', 'Mountain View'),),
570 (('organizationName', 'Google Inc'),)),
571 'subjectAltName': (('othername', 'blabla'),)}
572 fail(cert, 'google.com')
573
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000574 # Empty cert / no cert
575 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
576 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
577
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200578 # Issue #17980: avoid denials of service by refusing more than one
579 # wildcard per fragment.
580 cert = {'subject': ((('commonName', 'a*b.com'),),)}
581 ok(cert, 'axxb.com')
582 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
Georg Brandl72c98d32013-10-27 07:16:53 +0100583 fail(cert, 'axxb.com')
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200584 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
585 with self.assertRaises(ssl.CertificateError) as cm:
586 ssl.match_hostname(cert, 'axxbxxc.com')
587 self.assertIn("too many wildcards", str(cm.exception))
588
Antoine Pitroud5323212010-10-22 18:19:07 +0000589 def test_server_side(self):
590 # server_hostname doesn't work for server sockets
591 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000592 with socket.socket() as sock:
593 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
594 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000595
Antoine Pitroud6494802011-07-21 01:11:30 +0200596 def test_unknown_channel_binding(self):
597 # should raise ValueError for unknown type
598 s = socket.socket(socket.AF_INET)
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200599 s.bind(('127.0.0.1', 0))
600 s.listen()
601 c = socket.socket(socket.AF_INET)
602 c.connect(s.getsockname())
603 with ssl.wrap_socket(c, do_handshake_on_connect=False) as ss:
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100604 with self.assertRaises(ValueError):
605 ss.get_channel_binding("unknown-type")
Antoine Pitroub1fdf472014-10-05 20:41:53 +0200606 s.close()
Antoine Pitroud6494802011-07-21 01:11:30 +0200607
608 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
609 "'tls-unique' channel binding not available")
610 def test_tls_unique_channel_binding(self):
611 # unconnected should return None for known type
612 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100613 with ssl.wrap_socket(s) as ss:
614 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200615 # the same for server-side
616 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100617 with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
618 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200619
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600620 def test_dealloc_warn(self):
621 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
622 r = repr(ss)
623 with self.assertWarns(ResourceWarning) as cm:
624 ss = None
625 support.gc_collect()
626 self.assertIn(r, str(cm.warning.args[0]))
627
Christian Heimes6d7ad132013-06-09 18:02:55 +0200628 def test_get_default_verify_paths(self):
629 paths = ssl.get_default_verify_paths()
630 self.assertEqual(len(paths), 6)
631 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
632
633 with support.EnvironmentVarGuard() as env:
634 env["SSL_CERT_DIR"] = CAPATH
635 env["SSL_CERT_FILE"] = CERTFILE
636 paths = ssl.get_default_verify_paths()
637 self.assertEqual(paths.cafile, CERTFILE)
638 self.assertEqual(paths.capath, CAPATH)
639
Christian Heimes44109d72013-11-22 01:51:30 +0100640 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
641 def test_enum_certificates(self):
642 self.assertTrue(ssl.enum_certificates("CA"))
643 self.assertTrue(ssl.enum_certificates("ROOT"))
644
645 self.assertRaises(TypeError, ssl.enum_certificates)
646 self.assertRaises(WindowsError, ssl.enum_certificates, "")
647
Christian Heimesc2d65e12013-11-22 16:13:55 +0100648 trust_oids = set()
649 for storename in ("CA", "ROOT"):
650 store = ssl.enum_certificates(storename)
651 self.assertIsInstance(store, list)
652 for element in store:
653 self.assertIsInstance(element, tuple)
654 self.assertEqual(len(element), 3)
655 cert, enc, trust = element
656 self.assertIsInstance(cert, bytes)
657 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
658 self.assertIsInstance(trust, (set, bool))
659 if isinstance(trust, set):
660 trust_oids.update(trust)
Christian Heimes44109d72013-11-22 01:51:30 +0100661
662 serverAuth = "1.3.6.1.5.5.7.3.1"
Christian Heimesc2d65e12013-11-22 16:13:55 +0100663 self.assertIn(serverAuth, trust_oids)
Christian Heimes6d7ad132013-06-09 18:02:55 +0200664
Christian Heimes46bebee2013-06-09 19:03:31 +0200665 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Christian Heimes44109d72013-11-22 01:51:30 +0100666 def test_enum_crls(self):
667 self.assertTrue(ssl.enum_crls("CA"))
668 self.assertRaises(TypeError, ssl.enum_crls)
669 self.assertRaises(WindowsError, ssl.enum_crls, "")
Christian Heimes46bebee2013-06-09 19:03:31 +0200670
Christian Heimes44109d72013-11-22 01:51:30 +0100671 crls = ssl.enum_crls("CA")
672 self.assertIsInstance(crls, list)
673 for element in crls:
674 self.assertIsInstance(element, tuple)
675 self.assertEqual(len(element), 2)
676 self.assertIsInstance(element[0], bytes)
677 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
Christian Heimes46bebee2013-06-09 19:03:31 +0200678
Christian Heimes46bebee2013-06-09 19:03:31 +0200679
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100680 def test_asn1object(self):
681 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
682 '1.3.6.1.5.5.7.3.1')
683
684 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
685 self.assertEqual(val, expected)
686 self.assertEqual(val.nid, 129)
687 self.assertEqual(val.shortname, 'serverAuth')
688 self.assertEqual(val.longname, 'TLS Web Server Authentication')
689 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
690 self.assertIsInstance(val, ssl._ASN1Object)
691 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
692
693 val = ssl._ASN1Object.fromnid(129)
694 self.assertEqual(val, expected)
695 self.assertIsInstance(val, ssl._ASN1Object)
696 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100697 with self.assertRaisesRegex(ValueError, "unknown NID 100000"):
698 ssl._ASN1Object.fromnid(100000)
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100699 for i in range(1000):
700 try:
701 obj = ssl._ASN1Object.fromnid(i)
702 except ValueError:
703 pass
704 else:
705 self.assertIsInstance(obj.nid, int)
706 self.assertIsInstance(obj.shortname, str)
707 self.assertIsInstance(obj.longname, str)
708 self.assertIsInstance(obj.oid, (str, type(None)))
709
710 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
711 self.assertEqual(val, expected)
712 self.assertIsInstance(val, ssl._ASN1Object)
713 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
714 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
715 expected)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100716 with self.assertRaisesRegex(ValueError, "unknown object 'serverauth'"):
717 ssl._ASN1Object.fromname('serverauth')
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100718
Christian Heimes72d28502013-11-23 13:56:58 +0100719 def test_purpose_enum(self):
720 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
721 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
722 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
723 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
724 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
725 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
726 '1.3.6.1.5.5.7.3.1')
727
728 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
729 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
730 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
731 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
732 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
733 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
734 '1.3.6.1.5.5.7.3.2')
735
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100736 def test_unsupported_dtls(self):
737 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
738 self.addCleanup(s.close)
739 with self.assertRaises(NotImplementedError) as cx:
740 ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
741 self.assertEqual(str(cx.exception), "only stream sockets are supported")
742 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
743 with self.assertRaises(NotImplementedError) as cx:
744 ctx.wrap_socket(s)
745 self.assertEqual(str(cx.exception), "only stream sockets are supported")
746
Antoine Pitrouc695c952014-04-28 20:57:36 +0200747 def cert_time_ok(self, timestring, timestamp):
748 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
749
750 def cert_time_fail(self, timestring):
751 with self.assertRaises(ValueError):
752 ssl.cert_time_to_seconds(timestring)
753
754 @unittest.skipUnless(utc_offset(),
755 'local time needs to be different from UTC')
756 def test_cert_time_to_seconds_timezone(self):
757 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
758 # results if local timezone is not UTC
759 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
760 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
761
762 def test_cert_time_to_seconds(self):
763 timestring = "Jan 5 09:34:43 2018 GMT"
764 ts = 1515144883.0
765 self.cert_time_ok(timestring, ts)
766 # accept keyword parameter, assert its name
767 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
768 # accept both %e and %d (space or zero generated by strftime)
769 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
770 # case-insensitive
771 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
772 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
773 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
774 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
775 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
776 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
777 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
778 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
779
780 newyear_ts = 1230768000.0
781 # leap seconds
782 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
783 # same timestamp
784 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
785
786 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
787 # allow 60th second (even if it is not a leap second)
788 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
789 # allow 2nd leap second for compatibility with time.strptime()
790 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
791 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
792
793 # no special treatement for the special value:
794 # 99991231235959Z (rfc 5280)
795 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
796
797 @support.run_with_locale('LC_ALL', '')
798 def test_cert_time_to_seconds_locale(self):
799 # `cert_time_to_seconds()` should be locale independent
800
801 def local_february_name():
802 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
803
804 if local_february_name().lower() == 'feb':
805 self.skipTest("locale-specific month name needs to be "
806 "different from C locale")
807
808 # locale-independent
809 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
810 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
811
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100812
Antoine Pitrou152efa22010-05-16 18:19:27 +0000813class ContextTests(unittest.TestCase):
814
Antoine Pitrou23df4832010-08-04 17:14:06 +0000815 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000816 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100817 for protocol in PROTOCOLS:
818 ssl.SSLContext(protocol)
Christian Heimes598894f2016-09-05 23:19:05 +0200819 ctx = ssl.SSLContext()
820 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLS)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000821 self.assertRaises(ValueError, ssl.SSLContext, -1)
822 self.assertRaises(ValueError, ssl.SSLContext, 42)
823
Antoine Pitrou23df4832010-08-04 17:14:06 +0000824 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000825 def test_protocol(self):
826 for proto in PROTOCOLS:
827 ctx = ssl.SSLContext(proto)
828 self.assertEqual(ctx.protocol, proto)
829
830 def test_ciphers(self):
831 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
832 ctx.set_ciphers("ALL")
833 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000834 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000835 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000836
Antoine Pitrou23df4832010-08-04 17:14:06 +0000837 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000838 def test_options(self):
839 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800840 # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
Christian Heimes598894f2016-09-05 23:19:05 +0200841 default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
842 if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0):
843 default |= ssl.OP_NO_COMPRESSION
844 self.assertEqual(default, ctx.options)
Benjamin Petersona9dcdab2015-11-11 22:38:41 -0800845 ctx.options |= ssl.OP_NO_TLSv1
Christian Heimes598894f2016-09-05 23:19:05 +0200846 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000847 if can_clear_options():
Christian Heimes598894f2016-09-05 23:19:05 +0200848 ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
849 self.assertEqual(default, ctx.options)
Antoine Pitroub5218772010-05-21 09:56:06 +0000850 ctx.options = 0
Matthias Klosef7c56242016-06-12 23:40:00 -0700851 # Ubuntu has OP_NO_SSLv3 forced on by default
852 self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
Antoine Pitroub5218772010-05-21 09:56:06 +0000853 else:
854 with self.assertRaises(ValueError):
855 ctx.options = 0
856
Christian Heimes22587792013-11-21 23:56:13 +0100857 def test_verify_mode(self):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000858 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
859 # Default value
860 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
861 ctx.verify_mode = ssl.CERT_OPTIONAL
862 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
863 ctx.verify_mode = ssl.CERT_REQUIRED
864 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
865 ctx.verify_mode = ssl.CERT_NONE
866 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
867 with self.assertRaises(TypeError):
868 ctx.verify_mode = None
869 with self.assertRaises(ValueError):
870 ctx.verify_mode = 42
871
Christian Heimes2427b502013-11-23 11:24:32 +0100872 @unittest.skipUnless(have_verify_flags(),
873 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +0100874 def test_verify_flags(self):
875 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson990fcaa2015-03-04 22:49:41 -0500876 # default value
877 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
878 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +0100879 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
880 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
881 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
882 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
883 ctx.verify_flags = ssl.VERIFY_DEFAULT
884 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
885 # supports any value
886 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
887 self.assertEqual(ctx.verify_flags,
888 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
889 with self.assertRaises(TypeError):
890 ctx.verify_flags = None
891
Antoine Pitrou152efa22010-05-16 18:19:27 +0000892 def test_load_cert_chain(self):
893 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
894 # Combined key and cert in a single file
Benjamin Peterson1ea070e2014-11-03 21:05:01 -0500895 ctx.load_cert_chain(CERTFILE, keyfile=None)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000896 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
897 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200898 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000899 ctx.load_cert_chain(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000900 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000901 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000902 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000903 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000904 ctx.load_cert_chain(EMPTYCERT)
905 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000906 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000907 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
908 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
909 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000910 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000911 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000912 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000913 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000914 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000915 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
916 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000917 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000918 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Martin Panter3d81d932016-01-14 09:36:00 +0000919 ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200920 # Password protected key and cert
921 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
922 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
923 ctx.load_cert_chain(CERTFILE_PROTECTED,
924 password=bytearray(KEY_PASSWORD.encode()))
925 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
926 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
927 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
928 bytearray(KEY_PASSWORD.encode()))
929 with self.assertRaisesRegex(TypeError, "should be a string"):
930 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
931 with self.assertRaises(ssl.SSLError):
932 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
933 with self.assertRaisesRegex(ValueError, "cannot be longer"):
934 # openssl has a fixed limit on the password buffer.
935 # PEM_BUFSIZE is generally set to 1kb.
936 # Return a string larger than this.
937 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
938 # Password callback
939 def getpass_unicode():
940 return KEY_PASSWORD
941 def getpass_bytes():
942 return KEY_PASSWORD.encode()
943 def getpass_bytearray():
944 return bytearray(KEY_PASSWORD.encode())
945 def getpass_badpass():
946 return "badpass"
947 def getpass_huge():
948 return b'a' * (1024 * 1024)
949 def getpass_bad_type():
950 return 9
951 def getpass_exception():
952 raise Exception('getpass error')
953 class GetPassCallable:
954 def __call__(self):
955 return KEY_PASSWORD
956 def getpass(self):
957 return KEY_PASSWORD
958 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
959 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
960 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
961 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
962 ctx.load_cert_chain(CERTFILE_PROTECTED,
963 password=GetPassCallable().getpass)
964 with self.assertRaises(ssl.SSLError):
965 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
966 with self.assertRaisesRegex(ValueError, "cannot be longer"):
967 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
968 with self.assertRaisesRegex(TypeError, "must return a string"):
969 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
970 with self.assertRaisesRegex(Exception, "getpass error"):
971 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
972 # Make sure the password function isn't called if it isn't needed
973 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000974
975 def test_load_verify_locations(self):
976 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
977 ctx.load_verify_locations(CERTFILE)
978 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
979 ctx.load_verify_locations(BYTES_CERTFILE)
980 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
981 self.assertRaises(TypeError, ctx.load_verify_locations)
Christian Heimesefff7062013-11-21 03:35:02 +0100982 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200983 with self.assertRaises(OSError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +0000984 ctx.load_verify_locations(NONEXISTINGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000985 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000986 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000987 ctx.load_verify_locations(BADCERT)
988 ctx.load_verify_locations(CERTFILE, CAPATH)
989 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
990
Victor Stinner80f75e62011-01-29 11:31:20 +0000991 # Issue #10989: crash if the second argument type is invalid
992 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
993
Christian Heimesefff7062013-11-21 03:35:02 +0100994 def test_load_verify_cadata(self):
995 # test cadata
996 with open(CAFILE_CACERT) as f:
997 cacert_pem = f.read()
998 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
999 with open(CAFILE_NEURONIO) as f:
1000 neuronio_pem = f.read()
1001 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
1002
1003 # test PEM
1004 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1005 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
1006 ctx.load_verify_locations(cadata=cacert_pem)
1007 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
1008 ctx.load_verify_locations(cadata=neuronio_pem)
1009 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1010 # cert already in hash table
1011 ctx.load_verify_locations(cadata=neuronio_pem)
1012 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1013
1014 # combined
1015 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1016 combined = "\n".join((cacert_pem, neuronio_pem))
1017 ctx.load_verify_locations(cadata=combined)
1018 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1019
1020 # with junk around the certs
1021 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1022 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
1023 neuronio_pem, "tail"]
1024 ctx.load_verify_locations(cadata="\n".join(combined))
1025 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1026
1027 # test DER
1028 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1029 ctx.load_verify_locations(cadata=cacert_der)
1030 ctx.load_verify_locations(cadata=neuronio_der)
1031 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1032 # cert already in hash table
1033 ctx.load_verify_locations(cadata=cacert_der)
1034 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1035
1036 # combined
1037 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1038 combined = b"".join((cacert_der, neuronio_der))
1039 ctx.load_verify_locations(cadata=combined)
1040 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
1041
1042 # error cases
1043 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1044 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
1045
1046 with self.assertRaisesRegex(ssl.SSLError, "no start line"):
1047 ctx.load_verify_locations(cadata="broken")
1048 with self.assertRaisesRegex(ssl.SSLError, "not enough data"):
1049 ctx.load_verify_locations(cadata=b"broken")
1050
1051
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001052 def test_load_dh_params(self):
1053 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1054 ctx.load_dh_params(DHFILE)
1055 if os.name != 'nt':
1056 ctx.load_dh_params(BYTES_DHFILE)
1057 self.assertRaises(TypeError, ctx.load_dh_params)
1058 self.assertRaises(TypeError, ctx.load_dh_params, None)
1059 with self.assertRaises(FileNotFoundError) as cm:
Martin Panter407b62f2016-01-30 03:41:43 +00001060 ctx.load_dh_params(NONEXISTINGCERT)
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001061 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001062 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +01001063 ctx.load_dh_params(CERTFILE)
1064
Antoine Pitroueb585ad2010-10-22 18:24:20 +00001065 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +00001066 def test_session_stats(self):
1067 for proto in PROTOCOLS:
1068 ctx = ssl.SSLContext(proto)
1069 self.assertEqual(ctx.session_stats(), {
1070 'number': 0,
1071 'connect': 0,
1072 'connect_good': 0,
1073 'connect_renegotiate': 0,
1074 'accept': 0,
1075 'accept_good': 0,
1076 'accept_renegotiate': 0,
1077 'hits': 0,
1078 'misses': 0,
1079 'timeouts': 0,
1080 'cache_full': 0,
1081 })
1082
Antoine Pitrou664c2d12010-11-17 20:29:42 +00001083 def test_set_default_verify_paths(self):
1084 # There's not much we can do to test that it acts as expected,
1085 # so just check it doesn't crash or raise an exception.
1086 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1087 ctx.set_default_verify_paths()
1088
Antoine Pitrou501da612011-12-21 09:27:41 +01001089 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +01001090 def test_set_ecdh_curve(self):
1091 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1092 ctx.set_ecdh_curve("prime256v1")
1093 ctx.set_ecdh_curve(b"prime256v1")
1094 self.assertRaises(TypeError, ctx.set_ecdh_curve)
1095 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
1096 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
1097 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
1098
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001099 @needs_sni
1100 def test_sni_callback(self):
1101 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1102
1103 # set_servername_callback expects a callable, or None
1104 self.assertRaises(TypeError, ctx.set_servername_callback)
1105 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
1106 self.assertRaises(TypeError, ctx.set_servername_callback, "")
1107 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
1108
1109 def dummycallback(sock, servername, ctx):
1110 pass
1111 ctx.set_servername_callback(None)
1112 ctx.set_servername_callback(dummycallback)
1113
1114 @needs_sni
1115 def test_sni_callback_refcycle(self):
1116 # Reference cycles through the servername callback are detected
1117 # and cleared.
1118 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1119 def dummycallback(sock, servername, ctx, cycle=ctx):
1120 pass
1121 ctx.set_servername_callback(dummycallback)
1122 wr = weakref.ref(ctx)
1123 del ctx, dummycallback
1124 gc.collect()
1125 self.assertIs(wr(), None)
1126
Christian Heimes9a5395a2013-06-17 15:44:12 +02001127 def test_cert_store_stats(self):
1128 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1129 self.assertEqual(ctx.cert_store_stats(),
1130 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1131 ctx.load_cert_chain(CERTFILE)
1132 self.assertEqual(ctx.cert_store_stats(),
1133 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1134 ctx.load_verify_locations(CERTFILE)
1135 self.assertEqual(ctx.cert_store_stats(),
1136 {'x509_ca': 0, 'crl': 0, 'x509': 1})
Martin Panterb55f8b72016-01-14 12:53:56 +00001137 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001138 self.assertEqual(ctx.cert_store_stats(),
1139 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1140
1141 def test_get_ca_certs(self):
1142 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1143 self.assertEqual(ctx.get_ca_certs(), [])
1144 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1145 ctx.load_verify_locations(CERTFILE)
1146 self.assertEqual(ctx.get_ca_certs(), [])
Martin Panterb55f8b72016-01-14 12:53:56 +00001147 # but CAFILE_CACERT is a CA cert
1148 ctx.load_verify_locations(CAFILE_CACERT)
Christian Heimes9a5395a2013-06-17 15:44:12 +02001149 self.assertEqual(ctx.get_ca_certs(),
1150 [{'issuer': ((('organizationName', 'Root CA'),),
1151 (('organizationalUnitName', 'http://www.cacert.org'),),
1152 (('commonName', 'CA Cert Signing Authority'),),
1153 (('emailAddress', 'support@cacert.org'),)),
1154 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1155 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1156 'serialNumber': '00',
Christian Heimesbd3a7f92013-11-21 03:40:15 +01001157 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
Christian Heimes9a5395a2013-06-17 15:44:12 +02001158 'subject': ((('organizationName', 'Root CA'),),
1159 (('organizationalUnitName', 'http://www.cacert.org'),),
1160 (('commonName', 'CA Cert Signing Authority'),),
1161 (('emailAddress', 'support@cacert.org'),)),
1162 'version': 3}])
1163
Martin Panterb55f8b72016-01-14 12:53:56 +00001164 with open(CAFILE_CACERT) as f:
Christian Heimes9a5395a2013-06-17 15:44:12 +02001165 pem = f.read()
1166 der = ssl.PEM_cert_to_DER_cert(pem)
1167 self.assertEqual(ctx.get_ca_certs(True), [der])
1168
Christian Heimes72d28502013-11-23 13:56:58 +01001169 def test_load_default_certs(self):
1170 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1171 ctx.load_default_certs()
1172
1173 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1174 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1175 ctx.load_default_certs()
1176
1177 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1178 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1179
1180 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1181 self.assertRaises(TypeError, ctx.load_default_certs, None)
1182 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1183
Benjamin Peterson91244e02014-10-03 18:17:15 -04001184 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Christian Heimes598894f2016-09-05 23:19:05 +02001185 @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
Benjamin Peterson5915b0f2014-10-03 17:27:05 -04001186 def test_load_default_certs_env(self):
1187 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1188 with support.EnvironmentVarGuard() as env:
1189 env["SSL_CERT_DIR"] = CAPATH
1190 env["SSL_CERT_FILE"] = CERTFILE
1191 ctx.load_default_certs()
1192 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1193
Benjamin Peterson91244e02014-10-03 18:17:15 -04001194 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
1195 def test_load_default_certs_env_windows(self):
1196 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1197 ctx.load_default_certs()
1198 stats = ctx.cert_store_stats()
1199
1200 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1201 with support.EnvironmentVarGuard() as env:
1202 env["SSL_CERT_DIR"] = CAPATH
1203 env["SSL_CERT_FILE"] = CERTFILE
1204 ctx.load_default_certs()
1205 stats["x509"] += 1
1206 self.assertEqual(ctx.cert_store_stats(), stats)
1207
Christian Heimes4c05b472013-11-23 15:58:30 +01001208 def test_create_default_context(self):
1209 ctx = ssl.create_default_context()
Donald Stufft6a2ba942014-03-23 19:05:28 -04001210 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001211 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001212 self.assertTrue(ctx.check_hostname)
Christian Heimes4c05b472013-11-23 15:58:30 +01001213 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001214 self.assertEqual(
1215 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1216 getattr(ssl, "OP_NO_COMPRESSION", 0),
1217 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001218
1219 with open(SIGNING_CA) as f:
1220 cadata = f.read()
1221 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1222 cadata=cadata)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001223 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001224 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1225 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001226 self.assertEqual(
1227 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1228 getattr(ssl, "OP_NO_COMPRESSION", 0),
1229 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001230
1231 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001232 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
Christian Heimes4c05b472013-11-23 15:58:30 +01001233 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1234 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Donald Stufft6a2ba942014-03-23 19:05:28 -04001235 self.assertEqual(
1236 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1237 getattr(ssl, "OP_NO_COMPRESSION", 0),
1238 )
1239 self.assertEqual(
1240 ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0),
1241 getattr(ssl, "OP_SINGLE_DH_USE", 0),
1242 )
1243 self.assertEqual(
1244 ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1245 getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1246 )
Christian Heimes4c05b472013-11-23 15:58:30 +01001247
Christian Heimes67986f92013-11-23 22:43:47 +01001248 def test__create_stdlib_context(self):
1249 ctx = ssl._create_stdlib_context()
1250 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1251 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001252 self.assertFalse(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001253 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1254
1255 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1256 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1257 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1258 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1259
1260 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001261 cert_reqs=ssl.CERT_REQUIRED,
1262 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001263 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1264 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001265 self.assertTrue(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001266 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1267
1268 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1269 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1270 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1271 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Christian Heimes4c05b472013-11-23 15:58:30 +01001272
Christian Heimes1aa9a752013-12-02 02:41:19 +01001273 def test_check_hostname(self):
1274 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1275 self.assertFalse(ctx.check_hostname)
1276
1277 # Requires CERT_REQUIRED or CERT_OPTIONAL
1278 with self.assertRaises(ValueError):
1279 ctx.check_hostname = True
1280 ctx.verify_mode = ssl.CERT_REQUIRED
1281 self.assertFalse(ctx.check_hostname)
1282 ctx.check_hostname = True
1283 self.assertTrue(ctx.check_hostname)
1284
1285 ctx.verify_mode = ssl.CERT_OPTIONAL
1286 ctx.check_hostname = True
1287 self.assertTrue(ctx.check_hostname)
1288
1289 # Cannot set CERT_NONE with check_hostname enabled
1290 with self.assertRaises(ValueError):
1291 ctx.verify_mode = ssl.CERT_NONE
1292 ctx.check_hostname = False
1293 self.assertFalse(ctx.check_hostname)
1294
Antoine Pitrou152efa22010-05-16 18:19:27 +00001295
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001296class SSLErrorTests(unittest.TestCase):
1297
1298 def test_str(self):
1299 # The str() of a SSLError doesn't include the errno
1300 e = ssl.SSLError(1, "foo")
1301 self.assertEqual(str(e), "foo")
1302 self.assertEqual(e.errno, 1)
1303 # Same for a subclass
1304 e = ssl.SSLZeroReturnError(1, "foo")
1305 self.assertEqual(str(e), "foo")
1306 self.assertEqual(e.errno, 1)
1307
1308 def test_lib_reason(self):
1309 # Test the library and reason attributes
1310 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1311 with self.assertRaises(ssl.SSLError) as cm:
1312 ctx.load_dh_params(CERTFILE)
1313 self.assertEqual(cm.exception.library, 'PEM')
1314 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1315 s = str(cm.exception)
1316 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1317
1318 def test_subclass(self):
1319 # Check that the appropriate SSLError subclass is raised
1320 # (this only tests one of them)
1321 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1322 with socket.socket() as s:
1323 s.bind(("127.0.0.1", 0))
Charles-François Natali6e204602014-07-23 19:28:13 +01001324 s.listen()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001325 c = socket.socket()
1326 c.connect(s.getsockname())
1327 c.setblocking(False)
1328 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001329 with self.assertRaises(ssl.SSLWantReadError) as cm:
1330 c.do_handshake()
1331 s = str(cm.exception)
1332 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1333 # For compatibility
1334 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1335
1336
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001337class MemoryBIOTests(unittest.TestCase):
1338
1339 def test_read_write(self):
1340 bio = ssl.MemoryBIO()
1341 bio.write(b'foo')
1342 self.assertEqual(bio.read(), b'foo')
1343 self.assertEqual(bio.read(), b'')
1344 bio.write(b'foo')
1345 bio.write(b'bar')
1346 self.assertEqual(bio.read(), b'foobar')
1347 self.assertEqual(bio.read(), b'')
1348 bio.write(b'baz')
1349 self.assertEqual(bio.read(2), b'ba')
1350 self.assertEqual(bio.read(1), b'z')
1351 self.assertEqual(bio.read(1), b'')
1352
1353 def test_eof(self):
1354 bio = ssl.MemoryBIO()
1355 self.assertFalse(bio.eof)
1356 self.assertEqual(bio.read(), b'')
1357 self.assertFalse(bio.eof)
1358 bio.write(b'foo')
1359 self.assertFalse(bio.eof)
1360 bio.write_eof()
1361 self.assertFalse(bio.eof)
1362 self.assertEqual(bio.read(2), b'fo')
1363 self.assertFalse(bio.eof)
1364 self.assertEqual(bio.read(1), b'o')
1365 self.assertTrue(bio.eof)
1366 self.assertEqual(bio.read(), b'')
1367 self.assertTrue(bio.eof)
1368
1369 def test_pending(self):
1370 bio = ssl.MemoryBIO()
1371 self.assertEqual(bio.pending, 0)
1372 bio.write(b'foo')
1373 self.assertEqual(bio.pending, 3)
1374 for i in range(3):
1375 bio.read(1)
1376 self.assertEqual(bio.pending, 3-i-1)
1377 for i in range(3):
1378 bio.write(b'x')
1379 self.assertEqual(bio.pending, i+1)
1380 bio.read()
1381 self.assertEqual(bio.pending, 0)
1382
1383 def test_buffer_types(self):
1384 bio = ssl.MemoryBIO()
1385 bio.write(b'foo')
1386 self.assertEqual(bio.read(), b'foo')
1387 bio.write(bytearray(b'bar'))
1388 self.assertEqual(bio.read(), b'bar')
1389 bio.write(memoryview(b'baz'))
1390 self.assertEqual(bio.read(), b'baz')
1391
1392 def test_error_types(self):
1393 bio = ssl.MemoryBIO()
1394 self.assertRaises(TypeError, bio.write, 'foo')
1395 self.assertRaises(TypeError, bio.write, None)
1396 self.assertRaises(TypeError, bio.write, True)
1397 self.assertRaises(TypeError, bio.write, 1)
1398
1399
Bill Janssen6e027db2007-11-15 22:23:56 +00001400class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001401
Antoine Pitrou480a1242010-04-28 21:37:09 +00001402 def test_connect(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001403 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001404 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1405 cert_reqs=ssl.CERT_NONE)
1406 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001407 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001408 self.assertEqual({}, s.getpeercert())
1409 finally:
1410 s.close()
1411
1412 # this should fail because we have no verification certs
1413 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1414 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001415 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Martin Panter3d81d932016-01-14 09:36:00 +00001416 s.connect, (REMOTE_HOST, 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001417 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001418
Antoine Pitrou350c7222010-09-09 13:31:46 +00001419 # this should succeed because we specify the root cert
1420 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1421 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001422 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001423 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001424 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001425 self.assertTrue(s.getpeercert())
1426 finally:
1427 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001428
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001429 def test_connect_ex(self):
1430 # Issue #11326: check connect_ex() implementation
Martin Panter3d81d932016-01-14 09:36:00 +00001431 with support.transient_internet(REMOTE_HOST):
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001432 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1433 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001434 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001435 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001436 self.assertEqual(0, s.connect_ex((REMOTE_HOST, 443)))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001437 self.assertTrue(s.getpeercert())
1438 finally:
1439 s.close()
1440
1441 def test_non_blocking_connect_ex(self):
1442 # Issue #11326: non-blocking connect_ex() should allow handshake
1443 # to proceed after the socket gets ready.
Martin Panter3d81d932016-01-14 09:36:00 +00001444 with support.transient_internet(REMOTE_HOST):
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001445 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1446 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001447 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001448 do_handshake_on_connect=False)
1449 try:
1450 s.setblocking(False)
Martin Panter3d81d932016-01-14 09:36:00 +00001451 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +00001452 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1453 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001454 # Wait for connect to finish
1455 select.select([], [s], [], 5.0)
1456 # Non-blocking handshake
1457 while True:
1458 try:
1459 s.do_handshake()
1460 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001461 except ssl.SSLWantReadError:
1462 select.select([s], [], [], 5.0)
1463 except ssl.SSLWantWriteError:
1464 select.select([], [s], [], 5.0)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001465 # SSL established
1466 self.assertTrue(s.getpeercert())
1467 finally:
1468 s.close()
1469
Antoine Pitroub4410db2011-05-18 18:51:06 +02001470 def test_timeout_connect_ex(self):
1471 # Issue #12065: on a timeout, connect_ex() should return the original
1472 # errno (mimicking the behaviour of non-SSL sockets).
Martin Panter3d81d932016-01-14 09:36:00 +00001473 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub4410db2011-05-18 18:51:06 +02001474 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1475 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001476 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitroub4410db2011-05-18 18:51:06 +02001477 do_handshake_on_connect=False)
1478 try:
1479 s.settimeout(0.0000001)
Martin Panter3d81d932016-01-14 09:36:00 +00001480 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitroub4410db2011-05-18 18:51:06 +02001481 if rc == 0:
Martin Panter3d81d932016-01-14 09:36:00 +00001482 self.skipTest("REMOTE_HOST responded too quickly")
Antoine Pitroub4410db2011-05-18 18:51:06 +02001483 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1484 finally:
1485 s.close()
1486
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001487 def test_connect_ex_error(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001488 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001489 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1490 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter3d81d932016-01-14 09:36:00 +00001491 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001492 try:
Martin Panter3d81d932016-01-14 09:36:00 +00001493 rc = s.connect_ex((REMOTE_HOST, 444))
Christian Heimesde570742013-12-16 21:15:44 +01001494 # Issue #19919: Windows machines or VMs hosted on Windows
1495 # machines sometimes return EWOULDBLOCK.
Martin Panter73f55072016-01-14 12:21:02 +00001496 errors = (
Martin Panterfab75d92016-01-15 02:08:13 +00001497 errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
Martin Panter73f55072016-01-14 12:21:02 +00001498 errno.EWOULDBLOCK,
1499 )
1500 self.assertIn(rc, errors)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001501 finally:
1502 s.close()
1503
Antoine Pitrou152efa22010-05-16 18:19:27 +00001504 def test_connect_with_context(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001505 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001506 # Same as test_connect, but with a separately created context
1507 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1508 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001509 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001510 try:
1511 self.assertEqual({}, s.getpeercert())
1512 finally:
1513 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +00001514 # Same with a server hostname
1515 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
Martin Panter3d81d932016-01-14 09:36:00 +00001516 server_hostname=REMOTE_HOST)
Martin Panter514bb072016-01-14 12:46:49 +00001517 s.connect((REMOTE_HOST, 443))
Benjamin Peterson7243b572014-11-23 17:04:34 -06001518 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +00001519 # This should fail because we have no verification certs
1520 ctx.verify_mode = ssl.CERT_REQUIRED
1521 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +00001522 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Martin Panter3d81d932016-01-14 09:36:00 +00001523 s.connect, (REMOTE_HOST, 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001524 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +00001525 # This should succeed because we specify the root cert
Martin Panter3d81d932016-01-14 09:36:00 +00001526 ctx.load_verify_locations(REMOTE_ROOT_CERT)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001527 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001528 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001529 try:
1530 cert = s.getpeercert()
1531 self.assertTrue(cert)
1532 finally:
1533 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001534
1535 def test_connect_capath(self):
1536 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001537 # NOTE: the subject hashing algorithm has been changed between
1538 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1539 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001540 # filename) for this test to be portable across OpenSSL releases.
Martin Panter3d81d932016-01-14 09:36:00 +00001541 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001542 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1543 ctx.verify_mode = ssl.CERT_REQUIRED
1544 ctx.load_verify_locations(capath=CAPATH)
1545 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001546 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001547 try:
1548 cert = s.getpeercert()
1549 self.assertTrue(cert)
1550 finally:
1551 s.close()
1552 # Same with a bytes `capath` argument
1553 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1554 ctx.verify_mode = ssl.CERT_REQUIRED
1555 ctx.load_verify_locations(capath=BYTES_CAPATH)
1556 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001557 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001558 try:
1559 cert = s.getpeercert()
1560 self.assertTrue(cert)
1561 finally:
1562 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001563
Christian Heimesefff7062013-11-21 03:35:02 +01001564 def test_connect_cadata(self):
Martin Panterb55f8b72016-01-14 12:53:56 +00001565 with open(REMOTE_ROOT_CERT) as f:
Christian Heimesefff7062013-11-21 03:35:02 +01001566 pem = f.read()
1567 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panterb55f8b72016-01-14 12:53:56 +00001568 with support.transient_internet(REMOTE_HOST):
Christian Heimesefff7062013-11-21 03:35:02 +01001569 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1570 ctx.verify_mode = ssl.CERT_REQUIRED
1571 ctx.load_verify_locations(cadata=pem)
1572 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
Martin Panterb55f8b72016-01-14 12:53:56 +00001573 s.connect((REMOTE_HOST, 443))
Christian Heimesefff7062013-11-21 03:35:02 +01001574 cert = s.getpeercert()
1575 self.assertTrue(cert)
1576
1577 # same with DER
1578 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1579 ctx.verify_mode = ssl.CERT_REQUIRED
1580 ctx.load_verify_locations(cadata=der)
1581 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
Martin Panterb55f8b72016-01-14 12:53:56 +00001582 s.connect((REMOTE_HOST, 443))
Christian Heimesefff7062013-11-21 03:35:02 +01001583 cert = s.getpeercert()
1584 self.assertTrue(cert)
1585
Antoine Pitroue3220242010-04-24 11:13:53 +00001586 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1587 def test_makefile_close(self):
1588 # Issue #5238: creating a file-like object with makefile() shouldn't
1589 # delay closing the underlying "real socket" (here tested with its
1590 # file descriptor, hence skipping the test under Windows).
Martin Panter3d81d932016-01-14 09:36:00 +00001591 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001592 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter3d81d932016-01-14 09:36:00 +00001593 ss.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001594 fd = ss.fileno()
1595 f = ss.makefile()
1596 f.close()
1597 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +00001598 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001599 # Closing the SSL socket should close the fd too
1600 ss.close()
1601 gc.collect()
1602 with self.assertRaises(OSError) as e:
1603 os.read(fd, 0)
1604 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001605
Antoine Pitrou480a1242010-04-28 21:37:09 +00001606 def test_non_blocking_handshake(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001607 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001608 s = socket.socket(socket.AF_INET)
Martin Panter3d81d932016-01-14 09:36:00 +00001609 s.connect((REMOTE_HOST, 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001610 s.setblocking(False)
1611 s = ssl.wrap_socket(s,
1612 cert_reqs=ssl.CERT_NONE,
1613 do_handshake_on_connect=False)
1614 count = 0
1615 while True:
1616 try:
1617 count += 1
1618 s.do_handshake()
1619 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001620 except ssl.SSLWantReadError:
1621 select.select([s], [], [])
1622 except ssl.SSLWantWriteError:
1623 select.select([], [s], [])
Antoine Pitrou350c7222010-09-09 13:31:46 +00001624 s.close()
1625 if support.verbose:
1626 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001627
Antoine Pitrou480a1242010-04-28 21:37:09 +00001628 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +02001629 def _test_get_server_certificate(host, port, cert=None):
1630 with support.transient_internet(host):
Antoine Pitrou94a5b662014-04-16 18:56:28 +02001631 pem = ssl.get_server_certificate((host, port))
Antoine Pitrou15399c32011-04-28 19:23:55 +02001632 if not pem:
1633 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001634
Antoine Pitrou15399c32011-04-28 19:23:55 +02001635 try:
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001636 pem = ssl.get_server_certificate((host, port),
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001637 ca_certs=CERTFILE)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001638 except ssl.SSLError as x:
1639 #should fail
1640 if support.verbose:
1641 sys.stdout.write("%s\n" % x)
1642 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001643 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1644
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001645 pem = ssl.get_server_certificate((host, port),
Benjamin Peterson10b93cc2014-03-12 18:10:57 -05001646 ca_certs=cert)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001647 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001648 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001649 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001650 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001651
Martin Panter73f55072016-01-14 12:21:02 +00001652 _test_get_server_certificate(REMOTE_HOST, 443, REMOTE_ROOT_CERT)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001653 if support.IPV6_ENABLED:
1654 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001655
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001656 def test_ciphers(self):
Martin Panter3d81d932016-01-14 09:36:00 +00001657 remote = (REMOTE_HOST, 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001658 with support.transient_internet(remote[0]):
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001659 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1660 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1661 s.connect(remote)
1662 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1663 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1664 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001665 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +00001666 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +00001667 with socket.socket(socket.AF_INET) as sock:
1668 s = ssl.wrap_socket(sock,
1669 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1670 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001671
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001672 def test_algorithms(self):
1673 # Issue #8484: all algorithms should be available when verifying a
1674 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +00001675 # SHA256 was added in OpenSSL 0.9.8
1676 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1677 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001678 # sha256.tbs-internet.com needs SNI to use the correct certificate
1679 if not ssl.HAS_SNI:
1680 self.skipTest("SNI needed for this test")
Victor Stinnerf332abb2011-01-08 03:16:05 +00001681 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1682 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001683 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +00001684 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001685 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1686 ctx.verify_mode = ssl.CERT_REQUIRED
1687 ctx.load_verify_locations(sha256_cert)
1688 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1689 server_hostname="sha256.tbs-internet.com")
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001690 try:
1691 s.connect(remote)
1692 if support.verbose:
1693 sys.stdout.write("\nCipher with %r is %r\n" %
1694 (remote, s.cipher()))
1695 sys.stdout.write("Certificate is:\n%s\n" %
1696 pprint.pformat(s.getpeercert()))
1697 finally:
1698 s.close()
1699
Christian Heimes9a5395a2013-06-17 15:44:12 +02001700 def test_get_ca_certs_capath(self):
1701 # capath certs are loaded on request
Martin Panterb55f8b72016-01-14 12:53:56 +00001702 with support.transient_internet(REMOTE_HOST):
Christian Heimes9a5395a2013-06-17 15:44:12 +02001703 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1704 ctx.verify_mode = ssl.CERT_REQUIRED
1705 ctx.load_verify_locations(capath=CAPATH)
1706 self.assertEqual(ctx.get_ca_certs(), [])
1707 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panterb55f8b72016-01-14 12:53:56 +00001708 s.connect((REMOTE_HOST, 443))
Christian Heimes9a5395a2013-06-17 15:44:12 +02001709 try:
1710 cert = s.getpeercert()
1711 self.assertTrue(cert)
1712 finally:
1713 s.close()
1714 self.assertEqual(len(ctx.get_ca_certs()), 1)
1715
Christian Heimes575596e2013-12-15 21:49:17 +01001716 @needs_sni
Christian Heimes8e7f3942013-12-05 07:41:08 +01001717 def test_context_setget(self):
1718 # Check that the context of a connected socket can be replaced.
Martin Panterb55f8b72016-01-14 12:53:56 +00001719 with support.transient_internet(REMOTE_HOST):
Christian Heimes8e7f3942013-12-05 07:41:08 +01001720 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1721 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1722 s = socket.socket(socket.AF_INET)
1723 with ctx1.wrap_socket(s) as ss:
Martin Panterb55f8b72016-01-14 12:53:56 +00001724 ss.connect((REMOTE_HOST, 443))
Christian Heimes8e7f3942013-12-05 07:41:08 +01001725 self.assertIs(ss.context, ctx1)
1726 self.assertIs(ss._sslobj.context, ctx1)
1727 ss.context = ctx2
1728 self.assertIs(ss.context, ctx2)
1729 self.assertIs(ss._sslobj.context, ctx2)
1730
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001731
1732class NetworkedBIOTests(unittest.TestCase):
1733
1734 def ssl_io_loop(self, sock, incoming, outgoing, func, *args, **kwargs):
1735 # A simple IO loop. Call func(*args) depending on the error we get
1736 # (WANT_READ or WANT_WRITE) move data between the socket and the BIOs.
1737 timeout = kwargs.get('timeout', 10)
1738 count = 0
1739 while True:
1740 errno = None
1741 count += 1
1742 try:
1743 ret = func(*args)
1744 except ssl.SSLError as e:
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001745 if e.errno not in (ssl.SSL_ERROR_WANT_READ,
Martin Panter40b97ec2016-01-14 13:05:46 +00001746 ssl.SSL_ERROR_WANT_WRITE):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001747 raise
1748 errno = e.errno
1749 # Get any data from the outgoing BIO irrespective of any error, and
1750 # send it to the socket.
1751 buf = outgoing.read()
1752 sock.sendall(buf)
1753 # If there's no error, we're done. For WANT_READ, we need to get
1754 # data from the socket and put it in the incoming BIO.
1755 if errno is None:
1756 break
1757 elif errno == ssl.SSL_ERROR_WANT_READ:
1758 buf = sock.recv(32768)
1759 if buf:
1760 incoming.write(buf)
1761 else:
1762 incoming.write_eof()
1763 if support.verbose:
1764 sys.stdout.write("Needed %d calls to complete %s().\n"
1765 % (count, func.__name__))
1766 return ret
1767
1768 def test_handshake(self):
Martin Panter40b97ec2016-01-14 13:05:46 +00001769 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001770 sock = socket.socket(socket.AF_INET)
Martin Panter40b97ec2016-01-14 13:05:46 +00001771 sock.connect((REMOTE_HOST, 443))
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001772 incoming = ssl.MemoryBIO()
1773 outgoing = ssl.MemoryBIO()
1774 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1775 ctx.verify_mode = ssl.CERT_REQUIRED
Martin Panter40b97ec2016-01-14 13:05:46 +00001776 ctx.load_verify_locations(REMOTE_ROOT_CERT)
Benjamin Petersonf9284ae2014-11-23 17:06:39 -06001777 ctx.check_hostname = True
Martin Panter40b97ec2016-01-14 13:05:46 +00001778 sslobj = ctx.wrap_bio(incoming, outgoing, False, REMOTE_HOST)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001779 self.assertIs(sslobj._sslobj.owner, sslobj)
1780 self.assertIsNone(sslobj.cipher())
Christian Heimes598894f2016-09-05 23:19:05 +02001781 self.assertIsNotNone(sslobj.shared_ciphers())
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001782 self.assertRaises(ValueError, sslobj.getpeercert)
1783 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1784 self.assertIsNone(sslobj.get_channel_binding('tls-unique'))
1785 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1786 self.assertTrue(sslobj.cipher())
Christian Heimes598894f2016-09-05 23:19:05 +02001787 self.assertIsNotNone(sslobj.shared_ciphers())
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001788 self.assertTrue(sslobj.getpeercert())
1789 if 'tls-unique' in ssl.CHANNEL_BINDING_TYPES:
1790 self.assertTrue(sslobj.get_channel_binding('tls-unique'))
Martin Panter40b97ec2016-01-14 13:05:46 +00001791 try:
1792 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
1793 except ssl.SSLSyscallError:
1794 # self-signed.pythontest.net probably shuts down the TCP
1795 # connection without sending a secure shutdown message, and
1796 # this is reported as SSL_ERROR_SYSCALL
1797 pass
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001798 self.assertRaises(ssl.SSLError, sslobj.write, b'foo')
1799 sock.close()
1800
1801 def test_read_write_data(self):
Martin Panter40b97ec2016-01-14 13:05:46 +00001802 with support.transient_internet(REMOTE_HOST):
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001803 sock = socket.socket(socket.AF_INET)
Martin Panter40b97ec2016-01-14 13:05:46 +00001804 sock.connect((REMOTE_HOST, 443))
Antoine Pitroub1fdf472014-10-05 20:41:53 +02001805 incoming = ssl.MemoryBIO()
1806 outgoing = ssl.MemoryBIO()
1807 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1808 ctx.verify_mode = ssl.CERT_NONE
1809 sslobj = ctx.wrap_bio(incoming, outgoing, False)
1810 self.ssl_io_loop(sock, incoming, outgoing, sslobj.do_handshake)
1811 req = b'GET / HTTP/1.0\r\n\r\n'
1812 self.ssl_io_loop(sock, incoming, outgoing, sslobj.write, req)
1813 buf = self.ssl_io_loop(sock, incoming, outgoing, sslobj.read, 1024)
1814 self.assertEqual(buf[:5], b'HTTP/')
1815 self.ssl_io_loop(sock, incoming, outgoing, sslobj.unwrap)
1816 sock.close()
1817
1818
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001819try:
1820 import threading
1821except ImportError:
1822 _have_threads = False
1823else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001824 _have_threads = True
1825
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001826 from test.ssl_servers import make_https_server
1827
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001828 class ThreadedEchoServer(threading.Thread):
1829
1830 class ConnectionHandler(threading.Thread):
1831
1832 """A mildly complicated class, because we want it to work both
1833 with and without the SSL wrapper around the socket connection, so
1834 that we can test the STARTTLS functionality."""
1835
Bill Janssen6e027db2007-11-15 22:23:56 +00001836 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001837 self.server = server
1838 self.running = False
1839 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001840 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001841 self.sock.setblocking(1)
1842 self.sslconn = None
1843 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001844 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001845
Antoine Pitrou480a1242010-04-28 21:37:09 +00001846 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001847 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001848 self.sslconn = self.server.context.wrap_socket(
1849 self.sock, server_side=True)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001850 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1851 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001852 except (ssl.SSLError, ConnectionResetError) as e:
1853 # We treat ConnectionResetError as though it were an
1854 # SSLError - OpenSSL on Ubuntu abruptly closes the
1855 # connection when asked to use an unsupported protocol.
1856 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001857 # XXX Various errors can have happened here, for example
1858 # a mismatching protocol version, an invalid certificate,
1859 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001860 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001861 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001862 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001863 self.running = False
1864 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001865 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001866 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001867 else:
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001868 self.server.shared_ciphers.append(self.sslconn.shared_ciphers())
Antoine Pitroub5218772010-05-21 09:56:06 +00001869 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001870 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001871 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001872 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1873 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001874 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001875 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1876 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001877 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001878 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001879 sys.stdout.write(" server: selected protocol is now "
1880 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001881 return True
1882
1883 def read(self):
1884 if self.sslconn:
1885 return self.sslconn.read()
1886 else:
1887 return self.sock.recv(1024)
1888
1889 def write(self, bytes):
1890 if self.sslconn:
1891 return self.sslconn.write(bytes)
1892 else:
1893 return self.sock.send(bytes)
1894
1895 def close(self):
1896 if self.sslconn:
1897 self.sslconn.close()
1898 else:
1899 self.sock.close()
1900
Antoine Pitrou480a1242010-04-28 21:37:09 +00001901 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001902 self.running = True
1903 if not self.server.starttls_server:
1904 if not self.wrap_conn():
1905 return
1906 while self.running:
1907 try:
1908 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001909 stripped = msg.strip()
1910 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001911 # eof, so quit this handler
1912 self.running = False
1913 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001914 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001915 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001916 sys.stdout.write(" server: client closed connection\n")
1917 self.close()
1918 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001919 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001920 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001921 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001922 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001923 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001924 if not self.wrap_conn():
1925 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001926 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001927 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001928 if support.verbose and self.server.connectionchatty:
1929 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001930 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001931 self.sock = self.sslconn.unwrap()
1932 self.sslconn = None
1933 if support.verbose and self.server.connectionchatty:
1934 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001935 elif stripped == b'CB tls-unique':
1936 if support.verbose and self.server.connectionchatty:
1937 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1938 data = self.sslconn.get_channel_binding("tls-unique")
1939 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001940 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001941 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001942 self.server.connectionchatty):
1943 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001944 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1945 % (msg, ctype, msg.lower(), ctype))
1946 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001947 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001948 if self.server.chatty:
1949 handle_error("Test server failure:\n")
1950 self.close()
1951 self.running = False
1952 # normally, we'd just stop here, but for the test
1953 # harness, we want to stop the server
1954 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001955
Antoine Pitroub5218772010-05-21 09:56:06 +00001956 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001957 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001958 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersoncca27322015-01-23 16:35:37 -05001959 npn_protocols=None, alpn_protocols=None,
1960 ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00001961 if context:
1962 self.context = context
1963 else:
1964 self.context = ssl.SSLContext(ssl_version
1965 if ssl_version is not None
1966 else ssl.PROTOCOL_TLSv1)
1967 self.context.verify_mode = (certreqs if certreqs is not None
1968 else ssl.CERT_NONE)
1969 if cacerts:
1970 self.context.load_verify_locations(cacerts)
1971 if certificate:
1972 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001973 if npn_protocols:
1974 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05001975 if alpn_protocols:
1976 self.context.set_alpn_protocols(alpn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00001977 if ciphers:
1978 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001979 self.chatty = chatty
1980 self.connectionchatty = connectionchatty
1981 self.starttls_server = starttls_server
1982 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001983 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001984 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001985 self.active = False
Benjamin Petersoncca27322015-01-23 16:35:37 -05001986 self.selected_npn_protocols = []
1987 self.selected_alpn_protocols = []
Benjamin Peterson4cb17812015-01-07 11:14:26 -06001988 self.shared_ciphers = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001989 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001990 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001991 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001992
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001993 def __enter__(self):
1994 self.start(threading.Event())
1995 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001996 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001997
1998 def __exit__(self, *args):
1999 self.stop()
2000 self.join()
2001
Antoine Pitrou480a1242010-04-28 21:37:09 +00002002 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002003 self.flag = flag
2004 threading.Thread.start(self)
2005
Antoine Pitrou480a1242010-04-28 21:37:09 +00002006 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00002007 self.sock.settimeout(0.05)
Charles-François Natali6e204602014-07-23 19:28:13 +01002008 self.sock.listen()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002009 self.active = True
2010 if self.flag:
2011 # signal an event
2012 self.flag.set()
2013 while self.active:
2014 try:
2015 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002016 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002017 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00002018 + repr(connaddr) + '\n')
2019 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002020 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01002021 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002022 except socket.timeout:
2023 pass
2024 except KeyboardInterrupt:
2025 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00002026 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002027
Antoine Pitrou480a1242010-04-28 21:37:09 +00002028 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002029 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002030
Bill Janssen54cc54c2007-12-14 22:08:56 +00002031 class AsyncoreEchoServer(threading.Thread):
2032
2033 # this one's based on asyncore.dispatcher
2034
2035 class EchoServer (asyncore.dispatcher):
2036
2037 class ConnectionHandler (asyncore.dispatcher_with_send):
2038
2039 def __init__(self, conn, certfile):
2040 self.socket = ssl.wrap_socket(conn, server_side=True,
2041 certfile=certfile,
2042 do_handshake_on_connect=False)
2043 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002044 self._ssl_accepting = True
2045 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002046
2047 def readable(self):
2048 if isinstance(self.socket, ssl.SSLSocket):
2049 while self.socket.pending() > 0:
2050 self.handle_read_event()
2051 return True
2052
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002053 def _do_ssl_handshake(self):
2054 try:
2055 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02002056 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
2057 return
2058 except ssl.SSLEOFError:
2059 return self.handle_close()
2060 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002061 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002062 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002063 if err.args[0] == errno.ECONNABORTED:
2064 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00002065 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002066 self._ssl_accepting = False
2067
2068 def handle_read(self):
2069 if self._ssl_accepting:
2070 self._do_ssl_handshake()
2071 else:
2072 data = self.recv(1024)
2073 if support.verbose:
2074 sys.stdout.write(" server: read %s from client\n" % repr(data))
2075 if not data:
2076 self.close()
2077 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002078 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00002079
2080 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00002081 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002082 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002083 sys.stdout.write(" server: closed connection %s\n" % self.socket)
2084
2085 def handle_error(self):
2086 raise
2087
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002088 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002089 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002090 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
2091 self.port = support.bind_port(sock, '')
2092 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00002093 self.listen(5)
2094
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00002095 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002096 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00002097 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
2098 self.ConnectionHandler(sock_obj, self.certfile)
2099
2100 def handle_error(self):
2101 raise
2102
Trent Nelson78520002008-04-10 20:54:35 +00002103 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002104 self.flag = None
2105 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002106 self.server = self.EchoServer(certfile)
2107 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00002108 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00002109 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00002110
2111 def __str__(self):
2112 return "<%s %s>" % (self.__class__.__name__, self.server)
2113
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002114 def __enter__(self):
2115 self.start(threading.Event())
2116 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002117 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002118
2119 def __exit__(self, *args):
2120 if support.verbose:
2121 sys.stdout.write(" cleanup: stopping server.\n")
2122 self.stop()
2123 if support.verbose:
2124 sys.stdout.write(" cleanup: joining server thread.\n")
2125 self.join()
2126 if support.verbose:
2127 sys.stdout.write(" cleanup: successfully joined.\n")
2128
Bill Janssen54cc54c2007-12-14 22:08:56 +00002129 def start (self, flag=None):
2130 self.flag = flag
2131 threading.Thread.start(self)
2132
Antoine Pitrou480a1242010-04-28 21:37:09 +00002133 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002134 self.active = True
2135 if self.flag:
2136 self.flag.set()
2137 while self.active:
2138 try:
2139 asyncore.loop(1)
2140 except:
2141 pass
2142
Antoine Pitrou480a1242010-04-28 21:37:09 +00002143 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00002144 self.active = False
2145 self.server.close()
2146
Antoine Pitroub5218772010-05-21 09:56:06 +00002147 def server_params_test(client_context, server_context, indata=b"FOO\n",
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002148 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00002149 """
2150 Launch a server, connect a client to it and try various reads
2151 and writes.
2152 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002153 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00002154 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002155 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00002156 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002157 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002158 with client_context.wrap_socket(socket.socket(),
2159 server_hostname=sni_name) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002160 s.connect((HOST, server.port))
2161 for arg in [indata, bytearray(indata), memoryview(indata)]:
2162 if connectionchatty:
2163 if support.verbose:
2164 sys.stdout.write(
2165 " client: sending %r...\n" % indata)
2166 s.write(arg)
2167 outdata = s.read()
2168 if connectionchatty:
2169 if support.verbose:
2170 sys.stdout.write(" client: read %r\n" % outdata)
2171 if outdata != indata.lower():
2172 raise AssertionError(
2173 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2174 % (outdata[:20], len(outdata),
2175 indata[:20].lower(), len(indata)))
2176 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00002177 if connectionchatty:
2178 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01002179 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002180 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01002181 'compression': s.compression(),
2182 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002183 'peercert': s.getpeercert(),
Benjamin Petersoncca27322015-01-23 16:35:37 -05002184 'client_alpn_protocol': s.selected_alpn_protocol(),
Antoine Pitrou47e40422014-09-04 21:00:10 +02002185 'client_npn_protocol': s.selected_npn_protocol(),
2186 'version': s.version(),
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002187 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01002188 s.close()
Benjamin Petersoncca27322015-01-23 16:35:37 -05002189 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2190 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Peterson4cb17812015-01-07 11:14:26 -06002191 stats['server_shared_ciphers'] = server.shared_ciphers
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002192 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00002193
Antoine Pitroub5218772010-05-21 09:56:06 +00002194 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2195 certsreqs=None, server_options=0, client_options=0):
Antoine Pitrou47e40422014-09-04 21:00:10 +02002196 """
2197 Try to SSL-connect using *client_protocol* to *server_protocol*.
2198 If *expect_success* is true, assert that the connection succeeds,
2199 if it's false, assert that the connection fails.
2200 Also, if *expect_success* is a string, assert that it is the protocol
2201 version actually used by the connection.
2202 """
Benjamin Peterson2a691a82008-03-31 01:51:45 +00002203 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002204 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00002205 certtype = {
2206 ssl.CERT_NONE: "CERT_NONE",
2207 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2208 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2209 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002210 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002211 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002212 sys.stdout.write(formatstr %
2213 (ssl.get_protocol_name(client_protocol),
2214 ssl.get_protocol_name(server_protocol),
2215 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00002216 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002217 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00002218 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01002219 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002220
2221 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2222 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2223 # starting from OpenSSL 1.0.0 (see issue #8322).
2224 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2225 client_context.set_ciphers("ALL")
2226
Antoine Pitroub5218772010-05-21 09:56:06 +00002227 for ctx in (client_context, server_context):
2228 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00002229 ctx.load_cert_chain(CERTFILE)
2230 ctx.load_verify_locations(CERTFILE)
2231 try:
Antoine Pitrou47e40422014-09-04 21:00:10 +02002232 stats = server_params_test(client_context, server_context,
2233 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002234 # Protocol mismatch can result in either an SSLError, or a
2235 # "Connection reset by peer" error.
2236 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002237 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002238 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02002239 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002240 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002241 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002242 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002243 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00002244 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002245 "Client protocol %s succeeded with server protocol %s!"
2246 % (ssl.get_protocol_name(client_protocol),
2247 ssl.get_protocol_name(server_protocol)))
Antoine Pitrou47e40422014-09-04 21:00:10 +02002248 elif (expect_success is not True
2249 and expect_success != stats['version']):
2250 raise AssertionError("version mismatch: expected %r, got %r"
2251 % (expect_success, stats['version']))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002252
2253
Bill Janssen6e027db2007-11-15 22:23:56 +00002254 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002255
Antoine Pitrou23df4832010-08-04 17:14:06 +00002256 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002257 def test_echo(self):
2258 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002259 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002260 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002261 for protocol in PROTOCOLS:
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01002262 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
2263 context = ssl.SSLContext(protocol)
2264 context.load_cert_chain(CERTFILE)
2265 server_params_test(context, context,
2266 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002267
Antoine Pitrou480a1242010-04-28 21:37:09 +00002268 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002269 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002270 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00002271 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2272 context.verify_mode = ssl.CERT_REQUIRED
2273 context.load_verify_locations(CERTFILE)
2274 context.load_cert_chain(CERTFILE)
2275 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002276 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02002277 s = context.wrap_socket(socket.socket(),
2278 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002279 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02002280 # getpeercert() raise ValueError while the handshake isn't
2281 # done.
2282 with self.assertRaises(ValueError):
2283 s.getpeercert()
2284 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002285 cert = s.getpeercert()
2286 self.assertTrue(cert, "Can't get peer certificate.")
2287 cipher = s.cipher()
2288 if support.verbose:
2289 sys.stdout.write(pprint.pformat(cert) + '\n')
2290 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2291 if 'subject' not in cert:
2292 self.fail("No subject field in certificate: %s." %
2293 pprint.pformat(cert))
2294 if ((('organizationName', 'Python Software Foundation'),)
2295 not in cert['subject']):
2296 self.fail(
2297 "Missing or invalid 'organizationName' field in certificate subject; "
2298 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00002299 self.assertIn('notBefore', cert)
2300 self.assertIn('notAfter', cert)
2301 before = ssl.cert_time_to_seconds(cert['notBefore'])
2302 after = ssl.cert_time_to_seconds(cert['notAfter'])
2303 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002304 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002305
Christian Heimes2427b502013-11-23 11:24:32 +01002306 @unittest.skipUnless(have_verify_flags(),
2307 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01002308 def test_crl_check(self):
2309 if support.verbose:
2310 sys.stdout.write("\n")
2311
2312 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2313 server_context.load_cert_chain(SIGNED_CERTFILE)
2314
2315 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2316 context.verify_mode = ssl.CERT_REQUIRED
2317 context.load_verify_locations(SIGNING_CA)
Benjamin Petersonc3d9c5c2015-03-04 23:18:48 -05002318 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2319 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Christian Heimes22587792013-11-21 23:56:13 +01002320
2321 # VERIFY_DEFAULT should pass
2322 server = ThreadedEchoServer(context=server_context, chatty=True)
2323 with server:
2324 with context.wrap_socket(socket.socket()) as s:
2325 s.connect((HOST, server.port))
2326 cert = s.getpeercert()
2327 self.assertTrue(cert, "Can't get peer certificate.")
2328
2329 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01002330 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01002331
2332 server = ThreadedEchoServer(context=server_context, chatty=True)
2333 with server:
2334 with context.wrap_socket(socket.socket()) as s:
2335 with self.assertRaisesRegex(ssl.SSLError,
2336 "certificate verify failed"):
2337 s.connect((HOST, server.port))
2338
2339 # now load a CRL file. The CRL file is signed by the CA.
2340 context.load_verify_locations(CRLFILE)
2341
2342 server = ThreadedEchoServer(context=server_context, chatty=True)
2343 with server:
2344 with context.wrap_socket(socket.socket()) as s:
2345 s.connect((HOST, server.port))
2346 cert = s.getpeercert()
2347 self.assertTrue(cert, "Can't get peer certificate.")
2348
Christian Heimes1aa9a752013-12-02 02:41:19 +01002349 def test_check_hostname(self):
2350 if support.verbose:
2351 sys.stdout.write("\n")
2352
2353 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2354 server_context.load_cert_chain(SIGNED_CERTFILE)
2355
2356 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2357 context.verify_mode = ssl.CERT_REQUIRED
2358 context.check_hostname = True
2359 context.load_verify_locations(SIGNING_CA)
2360
2361 # correct hostname should verify
2362 server = ThreadedEchoServer(context=server_context, chatty=True)
2363 with server:
2364 with context.wrap_socket(socket.socket(),
2365 server_hostname="localhost") as s:
2366 s.connect((HOST, server.port))
2367 cert = s.getpeercert()
2368 self.assertTrue(cert, "Can't get peer certificate.")
2369
2370 # incorrect hostname should raise an exception
2371 server = ThreadedEchoServer(context=server_context, chatty=True)
2372 with server:
2373 with context.wrap_socket(socket.socket(),
2374 server_hostname="invalid") as s:
2375 with self.assertRaisesRegex(ssl.CertificateError,
2376 "hostname 'invalid' doesn't match 'localhost'"):
2377 s.connect((HOST, server.port))
2378
2379 # missing server_hostname arg should cause an exception, too
2380 server = ThreadedEchoServer(context=server_context, chatty=True)
2381 with server:
2382 with socket.socket() as s:
2383 with self.assertRaisesRegex(ValueError,
2384 "check_hostname requires server_hostname"):
2385 context.wrap_socket(s)
2386
Martin Panter407b62f2016-01-30 03:41:43 +00002387 def test_wrong_cert(self):
Martin Panter3464ea22016-02-01 21:58:11 +00002388 """Connecting when the server rejects the client's certificate
2389
2390 Launch a server with CERT_REQUIRED, and check that trying to
2391 connect to it with a wrong client certificate fails.
2392 """
2393 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2394 "wrongcert.pem")
2395 server = ThreadedEchoServer(CERTFILE,
2396 certreqs=ssl.CERT_REQUIRED,
2397 cacerts=CERTFILE, chatty=False,
2398 connectionchatty=False)
2399 with server, \
2400 socket.socket() as sock, \
2401 ssl.wrap_socket(sock,
2402 certfile=certfile,
2403 ssl_version=ssl.PROTOCOL_TLSv1) as s:
2404 try:
2405 # Expect either an SSL error about the server rejecting
2406 # the connection, or a low-level connection reset (which
2407 # sometimes happens on Windows)
2408 s.connect((HOST, server.port))
2409 except ssl.SSLError as e:
2410 if support.verbose:
2411 sys.stdout.write("\nSSLError is %r\n" % e)
2412 except OSError as e:
2413 if e.errno != errno.ECONNRESET:
2414 raise
2415 if support.verbose:
2416 sys.stdout.write("\nsocket.error is %r\n" % e)
2417 else:
2418 self.fail("Use of invalid cert should have failed!")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002419
Antoine Pitrou480a1242010-04-28 21:37:09 +00002420 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002421 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002422 in the client when attempting handshake.
2423 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002424 listener_ready = threading.Event()
2425 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002426
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002427 s = socket.socket()
2428 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002429
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002430 # `listener` runs in a thread. It sits in an accept() until
2431 # the main thread connects. Then it rudely closes the socket,
2432 # and sets Event `listener_gone` to let the main thread know
2433 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002434 def listener():
Charles-François Natali6e204602014-07-23 19:28:13 +01002435 s.listen()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002436 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002437 newsock, addr = s.accept()
2438 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002439 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002440 listener_gone.set()
2441
2442 def connector():
2443 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002444 with socket.socket() as c:
2445 c.connect((HOST, port))
2446 listener_gone.wait()
2447 try:
2448 ssl_sock = ssl.wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002449 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002450 pass
2451 else:
2452 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002453
2454 t = threading.Thread(target=listener)
2455 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002456 try:
2457 connector()
2458 finally:
2459 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002460
Antoine Pitrou23df4832010-08-04 17:14:06 +00002461 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002462 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2463 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002464 def test_protocol_sslv2(self):
2465 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002466 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002467 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002468 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2469 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2470 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002471 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Victor Stinner648b8622014-12-12 12:23:59 +01002472 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2473 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002474 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002475 # SSLv23 client with specific SSL options
2476 if no_sslv2_implies_sslv3_hello():
2477 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2478 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2479 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002480 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002481 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002482 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002483 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002484
Antoine Pitrou23df4832010-08-04 17:14:06 +00002485 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002486 def test_protocol_sslv23(self):
2487 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002488 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002489 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002490 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2491 try:
2492 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002493 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002494 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2495 if support.verbose:
2496 sys.stdout.write(
2497 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2498 % str(x))
Benjamin Petersone32467c2014-12-05 21:59:35 -05002499 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002500 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002501 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002502 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002503
Benjamin Petersone32467c2014-12-05 21:59:35 -05002504 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002505 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002506 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002507 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002508
Benjamin Petersone32467c2014-12-05 21:59:35 -05002509 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002510 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002511 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Antoine Pitrou47e40422014-09-04 21:00:10 +02002512 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002513
Antoine Pitroub5218772010-05-21 09:56:06 +00002514 # Server with specific SSL options
Benjamin Petersone32467c2014-12-05 21:59:35 -05002515 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2516 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002517 server_options=ssl.OP_NO_SSLv3)
2518 # Will choose TLSv1
2519 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2520 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2521 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2522 server_options=ssl.OP_NO_TLSv1)
2523
2524
Antoine Pitrou23df4832010-08-04 17:14:06 +00002525 @skip_if_broken_ubuntu_ssl
Benjamin Petersone32467c2014-12-05 21:59:35 -05002526 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2527 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002528 def test_protocol_sslv3(self):
2529 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002530 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002531 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002532 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2533 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2534 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002535 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2536 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002537 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2538 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002539 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002540 if no_sslv2_implies_sslv3_hello():
2541 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Petersona9dcdab2015-11-11 22:38:41 -08002542 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2543 False, client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002544
Antoine Pitrou23df4832010-08-04 17:14:06 +00002545 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002546 def test_protocol_tlsv1(self):
2547 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002548 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002549 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002550 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2551 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2552 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002553 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2554 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002555 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2556 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002557 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2558 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002559
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002560 @skip_if_broken_ubuntu_ssl
2561 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2562 "TLS version 1.1 not supported.")
2563 def test_protocol_tlsv1_1(self):
2564 """Connecting to a TLSv1.1 server with various client options.
2565 Testing against older TLS versions."""
2566 if support.verbose:
2567 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002568 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002569 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2570 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002571 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2572 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002573 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2574 client_options=ssl.OP_NO_TLSv1_1)
2575
Antoine Pitrou47e40422014-09-04 21:00:10 +02002576 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002577 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2578 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2579
2580
2581 @skip_if_broken_ubuntu_ssl
2582 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2583 "TLS version 1.2 not supported.")
2584 def test_protocol_tlsv1_2(self):
2585 """Connecting to a TLSv1.2 server with various client options.
2586 Testing against older TLS versions."""
2587 if support.verbose:
2588 sys.stdout.write("\n")
Antoine Pitrou47e40422014-09-04 21:00:10 +02002589 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002590 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2591 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2592 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2593 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersone32467c2014-12-05 21:59:35 -05002594 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2595 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002596 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2597 client_options=ssl.OP_NO_TLSv1_2)
2598
Antoine Pitrou47e40422014-09-04 21:00:10 +02002599 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002600 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2601 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2602 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2603 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2604
Antoine Pitrou480a1242010-04-28 21:37:09 +00002605 def test_starttls(self):
2606 """Switching from clear text to encrypted and back again."""
2607 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 +00002608
Trent Nelson78520002008-04-10 20:54:35 +00002609 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002610 ssl_version=ssl.PROTOCOL_TLSv1,
2611 starttls_server=True,
2612 chatty=True,
2613 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002614 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002615 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002616 s = socket.socket()
2617 s.setblocking(1)
2618 s.connect((HOST, server.port))
2619 if support.verbose:
2620 sys.stdout.write("\n")
2621 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002622 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002623 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002624 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002625 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002626 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002627 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002628 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002629 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002630 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002631 msg = outdata.strip().lower()
2632 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2633 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002634 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002635 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002636 " client: read %r from server, starting TLS...\n"
2637 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002638 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
2639 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002640 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2641 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002642 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002643 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002644 " client: read %r from server, ending TLS...\n"
2645 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002646 s = conn.unwrap()
2647 wrapped = False
2648 else:
2649 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002650 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002651 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002652 if support.verbose:
2653 sys.stdout.write(" client: closing connection.\n")
2654 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002655 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002656 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002657 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002658 if wrapped:
2659 conn.close()
2660 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002661 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002662
Antoine Pitrou480a1242010-04-28 21:37:09 +00002663 def test_socketserver(self):
2664 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002665 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002666 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002667 if support.verbose:
2668 sys.stdout.write('\n')
2669 with open(CERTFILE, 'rb') as f:
2670 d1 = f.read()
2671 d2 = ''
2672 # now fetch the same data from the HTTPS server
Benjamin Peterson4ffb0752014-11-03 14:29:33 -05002673 url = 'https://localhost:%d/%s' % (
2674 server.port, os.path.split(CERTFILE)[1])
2675 context = ssl.create_default_context(cafile=CERTFILE)
2676 f = urllib.request.urlopen(url, context=context)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002677 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002678 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002679 if dlen and (int(dlen) > 0):
2680 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002681 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002682 sys.stdout.write(
2683 " client: read %d bytes from remote server '%s'\n"
2684 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002685 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002686 f.close()
2687 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002688
Antoine Pitrou480a1242010-04-28 21:37:09 +00002689 def test_asyncore_server(self):
2690 """Check the example asyncore integration."""
2691 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00002692
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002693 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002694 sys.stdout.write("\n")
2695
Antoine Pitrou480a1242010-04-28 21:37:09 +00002696 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002697 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002698 with server:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002699 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002700 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002701 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002702 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002703 " client: sending %r...\n" % indata)
2704 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002705 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002706 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002707 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002708 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002709 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002710 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2711 % (outdata[:20], len(outdata),
2712 indata[:20].lower(), len(indata)))
2713 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002714 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002715 sys.stdout.write(" client: closing connection.\n")
2716 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002717 if support.verbose:
2718 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002719
Antoine Pitrou480a1242010-04-28 21:37:09 +00002720 def test_recv_send(self):
2721 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002722 if support.verbose:
2723 sys.stdout.write("\n")
2724
2725 server = ThreadedEchoServer(CERTFILE,
2726 certreqs=ssl.CERT_NONE,
2727 ssl_version=ssl.PROTOCOL_TLSv1,
2728 cacerts=CERTFILE,
2729 chatty=True,
2730 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002731 with server:
2732 s = ssl.wrap_socket(socket.socket(),
2733 server_side=False,
2734 certfile=CERTFILE,
2735 ca_certs=CERTFILE,
2736 cert_reqs=ssl.CERT_NONE,
2737 ssl_version=ssl.PROTOCOL_TLSv1)
2738 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002739 # helper methods for standardising recv* method signatures
2740 def _recv_into():
2741 b = bytearray(b"\0"*100)
2742 count = s.recv_into(b)
2743 return b[:count]
2744
2745 def _recvfrom_into():
2746 b = bytearray(b"\0"*100)
2747 count, addr = s.recvfrom_into(b)
2748 return b[:count]
2749
2750 # (name, method, whether to expect success, *args)
2751 send_methods = [
2752 ('send', s.send, True, []),
2753 ('sendto', s.sendto, False, ["some.address"]),
2754 ('sendall', s.sendall, True, []),
2755 ]
2756 recv_methods = [
2757 ('recv', s.recv, True, []),
2758 ('recvfrom', s.recvfrom, False, ["some.address"]),
2759 ('recv_into', _recv_into, True, []),
2760 ('recvfrom_into', _recvfrom_into, False, []),
2761 ]
2762 data_prefix = "PREFIX_"
2763
2764 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002765 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002766 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002767 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002768 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002769 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002770 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002771 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002772 "<<{outdata:r}>> ({nout:d}) received; "
2773 "expected <<{indata:r}>> ({nin:d})\n".format(
2774 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002775 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002776 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002777 )
2778 )
2779 except ValueError as e:
2780 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002781 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002782 "Failed to send with method <<{name:s}>>; "
2783 "expected to succeed.\n".format(name=meth_name)
2784 )
2785 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002786 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002787 "Method <<{name:s}>> failed with unexpected "
2788 "exception message: {exp:s}\n".format(
2789 name=meth_name, exp=e
2790 )
2791 )
2792
2793 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002794 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002795 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002796 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002797 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002798 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002799 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002800 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002801 "<<{outdata:r}>> ({nout:d}) received; "
2802 "expected <<{indata:r}>> ({nin:d})\n".format(
2803 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002804 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002805 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002806 )
2807 )
2808 except ValueError as e:
2809 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002810 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002811 "Failed to receive with method <<{name:s}>>; "
2812 "expected to succeed.\n".format(name=meth_name)
2813 )
2814 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002815 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002816 "Method <<{name:s}>> failed with unexpected "
2817 "exception message: {exp:s}\n".format(
2818 name=meth_name, exp=e
2819 )
2820 )
2821 # consume data
2822 s.read()
2823
Martin Panterf6b1d662016-03-28 00:22:09 +00002824 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panterbed7f1a2016-07-11 00:17:13 +00002825 data = b"data"
Martin Panter5503d472016-03-27 05:35:19 +00002826 s.send(data)
2827 buffer = bytearray(len(data))
2828 self.assertEqual(s.read(-1, buffer), len(data))
2829 self.assertEqual(buffer, data)
2830
Nick Coghlan513886a2011-08-28 00:00:27 +10002831 # Make sure sendmsg et al are disallowed to avoid
2832 # inadvertent disclosure of data and/or corruption
2833 # of the encrypted data stream
2834 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2835 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2836 self.assertRaises(NotImplementedError,
2837 s.recvmsg_into, bytearray(100))
2838
Antoine Pitrou480a1242010-04-28 21:37:09 +00002839 s.write(b"over\n")
Martin Panter5503d472016-03-27 05:35:19 +00002840
2841 self.assertRaises(ValueError, s.recv, -1)
2842 self.assertRaises(ValueError, s.read, -1)
2843
Bill Janssen58afe4c2008-09-08 16:45:19 +00002844 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002845
Martin Panterbed7f1a2016-07-11 00:17:13 +00002846 def test_recv_zero(self):
2847 server = ThreadedEchoServer(CERTFILE)
2848 server.__enter__()
2849 self.addCleanup(server.__exit__, None, None)
2850 s = socket.create_connection((HOST, server.port))
2851 self.addCleanup(s.close)
2852 s = ssl.wrap_socket(s, suppress_ragged_eofs=False)
2853 self.addCleanup(s.close)
2854
2855 # recv/read(0) should return no data
2856 s.send(b"data")
2857 self.assertEqual(s.recv(0), b"")
2858 self.assertEqual(s.read(0), b"")
2859 self.assertEqual(s.read(), b"data")
2860
2861 # Should not block if the other end sends no data
2862 s.setblocking(False)
2863 self.assertEqual(s.recv(0), b"")
2864 self.assertEqual(s.recv_into(bytearray()), 0)
2865
Antoine Pitroub4bebda2014-04-29 10:03:28 +02002866 def test_nonblocking_send(self):
2867 server = ThreadedEchoServer(CERTFILE,
2868 certreqs=ssl.CERT_NONE,
2869 ssl_version=ssl.PROTOCOL_TLSv1,
2870 cacerts=CERTFILE,
2871 chatty=True,
2872 connectionchatty=False)
2873 with server:
2874 s = ssl.wrap_socket(socket.socket(),
2875 server_side=False,
2876 certfile=CERTFILE,
2877 ca_certs=CERTFILE,
2878 cert_reqs=ssl.CERT_NONE,
2879 ssl_version=ssl.PROTOCOL_TLSv1)
2880 s.connect((HOST, server.port))
2881 s.setblocking(False)
2882
2883 # If we keep sending data, at some point the buffers
2884 # will be full and the call will block
2885 buf = bytearray(8192)
2886 def fill_buffer():
2887 while True:
2888 s.send(buf)
2889 self.assertRaises((ssl.SSLWantWriteError,
2890 ssl.SSLWantReadError), fill_buffer)
2891
2892 # Now read all the output and discard it
2893 s.setblocking(True)
2894 s.close()
2895
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002896 def test_handshake_timeout(self):
2897 # Issue #5103: SSL handshake must respect the socket timeout
2898 server = socket.socket(socket.AF_INET)
2899 host = "127.0.0.1"
2900 port = support.bind_port(server)
2901 started = threading.Event()
2902 finish = False
2903
2904 def serve():
Charles-François Natali6e204602014-07-23 19:28:13 +01002905 server.listen()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002906 started.set()
2907 conns = []
2908 while not finish:
2909 r, w, e = select.select([server], [], [], 0.1)
2910 if server in r:
2911 # Let the socket hang around rather than having
2912 # it closed by garbage collection.
2913 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00002914 for sock in conns:
2915 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002916
2917 t = threading.Thread(target=serve)
2918 t.start()
2919 started.wait()
2920
2921 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00002922 try:
2923 c = socket.socket(socket.AF_INET)
2924 c.settimeout(0.2)
2925 c.connect((host, port))
2926 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002927 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002928 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00002929 finally:
2930 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002931 try:
2932 c = socket.socket(socket.AF_INET)
2933 c = ssl.wrap_socket(c)
2934 c.settimeout(0.2)
2935 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002936 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002937 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002938 finally:
2939 c.close()
2940 finally:
2941 finish = True
2942 t.join()
2943 server.close()
2944
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002945 def test_server_accept(self):
2946 # Issue #16357: accept() on a SSLSocket created through
2947 # SSLContext.wrap_socket().
2948 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2949 context.verify_mode = ssl.CERT_REQUIRED
2950 context.load_verify_locations(CERTFILE)
2951 context.load_cert_chain(CERTFILE)
2952 server = socket.socket(socket.AF_INET)
2953 host = "127.0.0.1"
2954 port = support.bind_port(server)
2955 server = context.wrap_socket(server, server_side=True)
2956
2957 evt = threading.Event()
2958 remote = None
2959 peer = None
2960 def serve():
2961 nonlocal remote, peer
Charles-François Natali6e204602014-07-23 19:28:13 +01002962 server.listen()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002963 # Block on the accept and wait on the connection to close.
2964 evt.set()
2965 remote, peer = server.accept()
2966 remote.recv(1)
2967
2968 t = threading.Thread(target=serve)
2969 t.start()
2970 # Client wait until server setup and perform a connect.
2971 evt.wait()
2972 client = context.wrap_socket(socket.socket())
2973 client.connect((host, port))
2974 client_addr = client.getsockname()
2975 client.close()
2976 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002977 remote.close()
2978 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002979 # Sanity checks.
2980 self.assertIsInstance(remote, ssl.SSLSocket)
2981 self.assertEqual(peer, client_addr)
2982
Antoine Pitrou242db722013-05-01 20:52:07 +02002983 def test_getpeercert_enotconn(self):
2984 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2985 with context.wrap_socket(socket.socket()) as sock:
2986 with self.assertRaises(OSError) as cm:
2987 sock.getpeercert()
2988 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2989
2990 def test_do_handshake_enotconn(self):
2991 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2992 with context.wrap_socket(socket.socket()) as sock:
2993 with self.assertRaises(OSError) as cm:
2994 sock.do_handshake()
2995 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2996
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002997 def test_default_ciphers(self):
2998 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2999 try:
3000 # Force a set of weak ciphers on our client context
3001 context.set_ciphers("DES")
3002 except ssl.SSLError:
3003 self.skipTest("no DES cipher available")
3004 with ThreadedEchoServer(CERTFILE,
3005 ssl_version=ssl.PROTOCOL_SSLv23,
3006 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01003007 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02003008 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01003009 s.connect((HOST, server.port))
3010 self.assertIn("no shared cipher", str(server.conn_errors[0]))
3011
Antoine Pitrou47e40422014-09-04 21:00:10 +02003012 def test_version_basic(self):
3013 """
3014 Basic tests for SSLSocket.version().
3015 More tests are done in the test_protocol_*() methods.
3016 """
3017 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3018 with ThreadedEchoServer(CERTFILE,
3019 ssl_version=ssl.PROTOCOL_TLSv1,
3020 chatty=False) as server:
3021 with context.wrap_socket(socket.socket()) as s:
3022 self.assertIs(s.version(), None)
3023 s.connect((HOST, server.port))
Christian Heimes598894f2016-09-05 23:19:05 +02003024 self.assertEqual(s.version(), 'TLSv1')
Antoine Pitrou47e40422014-09-04 21:00:10 +02003025 self.assertIs(s.version(), None)
3026
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003027 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
3028 def test_default_ecdh_curve(self):
3029 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
3030 # should be enabled by default on SSL contexts.
3031 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3032 context.load_cert_chain(CERTFILE)
Antoine Pitrouc0430612014-04-16 18:33:39 +02003033 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
3034 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
3035 # our default cipher list should prefer ECDH-based ciphers
3036 # automatically.
3037 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
3038 context.set_ciphers("ECCdraft:ECDH")
Antoine Pitrou0bebbc32014-03-22 18:13:50 +01003039 with ThreadedEchoServer(context=context) as server:
3040 with context.wrap_socket(socket.socket()) as s:
3041 s.connect((HOST, server.port))
3042 self.assertIn("ECDH", s.cipher()[0])
3043
Antoine Pitroud6494802011-07-21 01:11:30 +02003044 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
3045 "'tls-unique' channel binding not available")
3046 def test_tls_unique_channel_binding(self):
3047 """Test tls-unique channel binding."""
3048 if support.verbose:
3049 sys.stdout.write("\n")
3050
3051 server = ThreadedEchoServer(CERTFILE,
3052 certreqs=ssl.CERT_NONE,
3053 ssl_version=ssl.PROTOCOL_TLSv1,
3054 cacerts=CERTFILE,
3055 chatty=True,
3056 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01003057 with server:
3058 s = ssl.wrap_socket(socket.socket(),
3059 server_side=False,
3060 certfile=CERTFILE,
3061 ca_certs=CERTFILE,
3062 cert_reqs=ssl.CERT_NONE,
3063 ssl_version=ssl.PROTOCOL_TLSv1)
3064 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02003065 # get the data
3066 cb_data = s.get_channel_binding("tls-unique")
3067 if support.verbose:
3068 sys.stdout.write(" got channel binding data: {0!r}\n"
3069 .format(cb_data))
3070
3071 # check if it is sane
3072 self.assertIsNotNone(cb_data)
3073 self.assertEqual(len(cb_data), 12) # True for TLSv1
3074
3075 # and compare with the peers version
3076 s.write(b"CB tls-unique\n")
3077 peer_data_repr = s.read().strip()
3078 self.assertEqual(peer_data_repr,
3079 repr(cb_data).encode("us-ascii"))
3080 s.close()
3081
3082 # now, again
3083 s = ssl.wrap_socket(socket.socket(),
3084 server_side=False,
3085 certfile=CERTFILE,
3086 ca_certs=CERTFILE,
3087 cert_reqs=ssl.CERT_NONE,
3088 ssl_version=ssl.PROTOCOL_TLSv1)
3089 s.connect((HOST, server.port))
3090 new_cb_data = s.get_channel_binding("tls-unique")
3091 if support.verbose:
3092 sys.stdout.write(" got another channel binding data: {0!r}\n"
3093 .format(new_cb_data))
3094 # is it really unique
3095 self.assertNotEqual(cb_data, new_cb_data)
3096 self.assertIsNotNone(cb_data)
3097 self.assertEqual(len(cb_data), 12) # True for TLSv1
3098 s.write(b"CB tls-unique\n")
3099 peer_data_repr = s.read().strip()
3100 self.assertEqual(peer_data_repr,
3101 repr(new_cb_data).encode("us-ascii"))
3102 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00003103
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003104 def test_compression(self):
3105 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3106 context.load_cert_chain(CERTFILE)
3107 stats = server_params_test(context, context,
3108 chatty=True, connectionchatty=True)
3109 if support.verbose:
3110 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
3111 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
3112
3113 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
3114 "ssl.OP_NO_COMPRESSION needed for this test")
3115 def test_compression_disabled(self):
3116 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3117 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01003118 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003119 stats = server_params_test(context, context,
3120 chatty=True, connectionchatty=True)
3121 self.assertIs(stats['compression'], None)
3122
Antoine Pitrou0e576f12011-12-22 10:03:38 +01003123 def test_dh_params(self):
3124 # Check we can get a connection with ephemeral Diffie-Hellman
3125 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3126 context.load_cert_chain(CERTFILE)
3127 context.load_dh_params(DHFILE)
3128 context.set_ciphers("kEDH")
3129 stats = server_params_test(context, context,
3130 chatty=True, connectionchatty=True)
3131 cipher = stats["cipher"][0]
3132 parts = cipher.split("-")
3133 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
3134 self.fail("Non-DH cipher: " + cipher[0])
3135
Benjamin Petersoncca27322015-01-23 16:35:37 -05003136 def test_selected_alpn_protocol(self):
3137 # selected_alpn_protocol() is None unless ALPN is used.
3138 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3139 context.load_cert_chain(CERTFILE)
3140 stats = server_params_test(context, context,
3141 chatty=True, connectionchatty=True)
3142 self.assertIs(stats['client_alpn_protocol'], None)
3143
3144 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
3145 def test_selected_alpn_protocol_if_server_uses_alpn(self):
3146 # selected_alpn_protocol() is None unless ALPN is used by the client.
3147 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3148 client_context.load_verify_locations(CERTFILE)
3149 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3150 server_context.load_cert_chain(CERTFILE)
3151 server_context.set_alpn_protocols(['foo', 'bar'])
3152 stats = server_params_test(client_context, server_context,
3153 chatty=True, connectionchatty=True)
3154 self.assertIs(stats['client_alpn_protocol'], None)
3155
3156 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
3157 def test_alpn_protocols(self):
3158 server_protocols = ['foo', 'bar', 'milkshake']
3159 protocol_tests = [
3160 (['foo', 'bar'], 'foo'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003161 (['bar', 'foo'], 'foo'),
Benjamin Petersoncca27322015-01-23 16:35:37 -05003162 (['milkshake'], 'milkshake'),
Benjamin Peterson88615022015-01-23 17:30:26 -05003163 (['http/3.0', 'http/4.0'], None)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003164 ]
3165 for client_protocols, expected in protocol_tests:
Christian Heimes598894f2016-09-05 23:19:05 +02003166 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003167 server_context.load_cert_chain(CERTFILE)
3168 server_context.set_alpn_protocols(server_protocols)
Christian Heimes598894f2016-09-05 23:19:05 +02003169 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003170 client_context.load_cert_chain(CERTFILE)
3171 client_context.set_alpn_protocols(client_protocols)
Benjamin Petersoncca27322015-01-23 16:35:37 -05003172
Christian Heimes598894f2016-09-05 23:19:05 +02003173 try:
3174 stats = server_params_test(client_context,
3175 server_context,
3176 chatty=True,
3177 connectionchatty=True)
3178 except ssl.SSLError as e:
3179 stats = e
3180
3181 if expected is None and IS_OPENSSL_1_1:
3182 # OpenSSL 1.1.0 raises handshake error
3183 self.assertIsInstance(stats, ssl.SSLError)
3184 else:
3185 msg = "failed trying %s (s) and %s (c).\n" \
3186 "was expecting %s, but got %%s from the %%s" \
3187 % (str(server_protocols), str(client_protocols),
3188 str(expected))
3189 client_result = stats['client_alpn_protocol']
3190 self.assertEqual(client_result, expected,
3191 msg % (client_result, "client"))
3192 server_result = stats['server_alpn_protocols'][-1] \
3193 if len(stats['server_alpn_protocols']) else 'nothing'
3194 self.assertEqual(server_result, expected,
3195 msg % (server_result, "server"))
Benjamin Petersoncca27322015-01-23 16:35:37 -05003196
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01003197 def test_selected_npn_protocol(self):
3198 # selected_npn_protocol() is None unless NPN is used
3199 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3200 context.load_cert_chain(CERTFILE)
3201 stats = server_params_test(context, context,
3202 chatty=True, connectionchatty=True)
3203 self.assertIs(stats['client_npn_protocol'], None)
3204
3205 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
3206 def test_npn_protocols(self):
3207 server_protocols = ['http/1.1', 'spdy/2']
3208 protocol_tests = [
3209 (['http/1.1', 'spdy/2'], 'http/1.1'),
3210 (['spdy/2', 'http/1.1'], 'http/1.1'),
3211 (['spdy/2', 'test'], 'spdy/2'),
3212 (['abc', 'def'], 'abc')
3213 ]
3214 for client_protocols, expected in protocol_tests:
3215 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3216 server_context.load_cert_chain(CERTFILE)
3217 server_context.set_npn_protocols(server_protocols)
3218 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3219 client_context.load_cert_chain(CERTFILE)
3220 client_context.set_npn_protocols(client_protocols)
3221 stats = server_params_test(client_context, server_context,
3222 chatty=True, connectionchatty=True)
3223
3224 msg = "failed trying %s (s) and %s (c).\n" \
3225 "was expecting %s, but got %%s from the %%s" \
3226 % (str(server_protocols), str(client_protocols),
3227 str(expected))
3228 client_result = stats['client_npn_protocol']
3229 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3230 server_result = stats['server_npn_protocols'][-1] \
3231 if len(stats['server_npn_protocols']) else 'nothing'
3232 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3233
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003234 def sni_contexts(self):
3235 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3236 server_context.load_cert_chain(SIGNED_CERTFILE)
3237 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3238 other_context.load_cert_chain(SIGNED_CERTFILE2)
3239 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3240 client_context.verify_mode = ssl.CERT_REQUIRED
3241 client_context.load_verify_locations(SIGNING_CA)
3242 return server_context, other_context, client_context
3243
3244 def check_common_name(self, stats, name):
3245 cert = stats['peercert']
3246 self.assertIn((('commonName', name),), cert['subject'])
3247
3248 @needs_sni
3249 def test_sni_callback(self):
3250 calls = []
3251 server_context, other_context, client_context = self.sni_contexts()
3252
3253 def servername_cb(ssl_sock, server_name, initial_context):
3254 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003255 if server_name is not None:
3256 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003257 server_context.set_servername_callback(servername_cb)
3258
3259 stats = server_params_test(client_context, server_context,
3260 chatty=True,
3261 sni_name='supermessage')
3262 # The hostname was fetched properly, and the certificate was
3263 # changed for the connection.
3264 self.assertEqual(calls, [("supermessage", server_context)])
3265 # CERTFILE4 was selected
3266 self.check_common_name(stats, 'fakehostname')
3267
Antoine Pitrou50b24d02013-04-11 20:48:42 +02003268 calls = []
3269 # The callback is called with server_name=None
3270 stats = server_params_test(client_context, server_context,
3271 chatty=True,
3272 sni_name=None)
3273 self.assertEqual(calls, [(None, server_context)])
3274 self.check_common_name(stats, 'localhost')
3275
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003276 # Check disabling the callback
3277 calls = []
3278 server_context.set_servername_callback(None)
3279
3280 stats = server_params_test(client_context, server_context,
3281 chatty=True,
3282 sni_name='notfunny')
3283 # Certificate didn't change
3284 self.check_common_name(stats, 'localhost')
3285 self.assertEqual(calls, [])
3286
3287 @needs_sni
3288 def test_sni_callback_alert(self):
3289 # Returning a TLS alert is reflected to the connecting client
3290 server_context, other_context, client_context = self.sni_contexts()
3291
3292 def cb_returning_alert(ssl_sock, server_name, initial_context):
3293 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3294 server_context.set_servername_callback(cb_returning_alert)
3295
3296 with self.assertRaises(ssl.SSLError) as cm:
3297 stats = server_params_test(client_context, server_context,
3298 chatty=False,
3299 sni_name='supermessage')
3300 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3301
3302 @needs_sni
3303 def test_sni_callback_raising(self):
3304 # Raising fails the connection with a TLS handshake failure alert.
3305 server_context, other_context, client_context = self.sni_contexts()
3306
3307 def cb_raising(ssl_sock, server_name, initial_context):
3308 1/0
3309 server_context.set_servername_callback(cb_raising)
3310
3311 with self.assertRaises(ssl.SSLError) as cm, \
3312 support.captured_stderr() as stderr:
3313 stats = server_params_test(client_context, server_context,
3314 chatty=False,
3315 sni_name='supermessage')
3316 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3317 self.assertIn("ZeroDivisionError", stderr.getvalue())
3318
3319 @needs_sni
3320 def test_sni_callback_wrong_return_type(self):
3321 # Returning the wrong return type terminates the TLS connection
3322 # with an internal error alert.
3323 server_context, other_context, client_context = self.sni_contexts()
3324
3325 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3326 return "foo"
3327 server_context.set_servername_callback(cb_wrong_return_type)
3328
3329 with self.assertRaises(ssl.SSLError) as cm, \
3330 support.captured_stderr() as stderr:
3331 stats = server_params_test(client_context, server_context,
3332 chatty=False,
3333 sni_name='supermessage')
3334 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3335 self.assertIn("TypeError", stderr.getvalue())
3336
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003337 def test_shared_ciphers(self):
Benjamin Petersonaacd5242015-01-07 11:42:38 -06003338 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson15042922015-01-07 22:12:43 -06003339 server_context.load_cert_chain(SIGNED_CERTFILE)
3340 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3341 client_context.verify_mode = ssl.CERT_REQUIRED
3342 client_context.load_verify_locations(SIGNING_CA)
Christian Heimes598894f2016-09-05 23:19:05 +02003343 if ssl.OPENSSL_VERSION_INFO >= (1, 0, 2):
3344 client_context.set_ciphers("AES128:AES256")
3345 server_context.set_ciphers("AES256")
3346 alg1 = "AES256"
3347 alg2 = "AES-256"
3348 else:
3349 client_context.set_ciphers("AES:3DES")
3350 server_context.set_ciphers("3DES")
3351 alg1 = "3DES"
3352 alg2 = "DES-CBC3"
3353
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003354 stats = server_params_test(client_context, server_context)
3355 ciphers = stats['server_shared_ciphers'][0]
3356 self.assertGreater(len(ciphers), 0)
3357 for name, tls_version, bits in ciphers:
Christian Heimes598894f2016-09-05 23:19:05 +02003358 if not alg1 in name.split("-") and alg2 not in name:
3359 self.fail(name)
Benjamin Peterson4cb17812015-01-07 11:14:26 -06003360
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003361 def test_read_write_after_close_raises_valuerror(self):
3362 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3363 context.verify_mode = ssl.CERT_REQUIRED
3364 context.load_verify_locations(CERTFILE)
3365 context.load_cert_chain(CERTFILE)
3366 server = ThreadedEchoServer(context=context, chatty=False)
3367
3368 with server:
3369 s = context.wrap_socket(socket.socket())
3370 s.connect((HOST, server.port))
3371 s.close()
3372
3373 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02003374 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02003375
Giampaolo Rodola'915d1412014-06-11 03:54:30 +02003376 def test_sendfile(self):
3377 TEST_DATA = b"x" * 512
3378 with open(support.TESTFN, 'wb') as f:
3379 f.write(TEST_DATA)
3380 self.addCleanup(support.unlink, support.TESTFN)
3381 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3382 context.verify_mode = ssl.CERT_REQUIRED
3383 context.load_verify_locations(CERTFILE)
3384 context.load_cert_chain(CERTFILE)
3385 server = ThreadedEchoServer(context=context, chatty=False)
3386 with server:
3387 with context.wrap_socket(socket.socket()) as s:
3388 s.connect((HOST, server.port))
3389 with open(support.TESTFN, 'rb') as file:
3390 s.sendfile(file)
3391 self.assertEqual(s.recv(1024), TEST_DATA)
3392
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01003393
Thomas Woutersed03b412007-08-28 21:37:11 +00003394def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00003395 if support.verbose:
Berker Peksag9e7990a2015-05-16 23:21:26 +03003396 import warnings
Antoine Pitrou15cee622010-08-04 16:45:21 +00003397 plats = {
3398 'Linux': platform.linux_distribution,
3399 'Mac': platform.mac_ver,
3400 'Windows': platform.win32_ver,
3401 }
Berker Peksag9e7990a2015-05-16 23:21:26 +03003402 with warnings.catch_warnings():
3403 warnings.filterwarnings(
3404 'ignore',
3405 'dist\(\) and linux_distribution\(\) '
3406 'functions are deprecated .*',
3407 PendingDeprecationWarning,
3408 )
3409 for name, func in plats.items():
3410 plat = func()
3411 if plat and plat[0]:
3412 plat = '%s %r' % (name, plat)
3413 break
3414 else:
3415 plat = repr(platform.platform())
Antoine Pitrou15cee622010-08-04 16:45:21 +00003416 print("test_ssl: testing with %r %r" %
3417 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3418 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00003419 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01003420 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3421 try:
3422 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3423 except AttributeError:
3424 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00003425
Antoine Pitrou152efa22010-05-16 18:19:27 +00003426 for filename in [
Martin Panter3d81d932016-01-14 09:36:00 +00003427 CERTFILE, REMOTE_ROOT_CERT, BYTES_CERTFILE,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003428 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01003429 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00003430 BADCERT, BADKEY, EMPTYCERT]:
3431 if not os.path.exists(filename):
3432 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003433
Antoine Pitroub1fdf472014-10-05 20:41:53 +02003434 tests = [ContextTests, BasicSocketTests, SSLErrorTests, MemoryBIOTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00003435
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003436 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00003437 tests.append(NetworkedTests)
Antoine Pitroub1fdf472014-10-05 20:41:53 +02003438 tests.append(NetworkedBIOTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003439
Thomas Wouters1b7f8912007-09-19 03:06:30 +00003440 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003441 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01003442 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00003443 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00003444
Antoine Pitrou480a1242010-04-28 21:37:09 +00003445 try:
3446 support.run_unittest(*tests)
3447 finally:
3448 if _have_threads:
3449 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00003450
3451if __name__ == "__main__":
3452 test_main()