blob: 1a2a9f0caa980826d9d18800bb06b9f78713adf9 [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
Antoine Pitrou242db722013-05-01 20:52:07 +020021from unittest import mock
Thomas Woutersed03b412007-08-28 21:37:11 +000022
Antoine Pitrou05d936d2010-10-13 11:38:36 +000023ssl = support.import_module("ssl")
24
Antoine Pitrou2463e5f2013-03-28 22:24:43 +010025PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
Benjamin Petersonee8712c2008-05-20 21:35:26 +000026HOST = support.HOST
Antoine Pitrou152efa22010-05-16 18:19:27 +000027
Christian Heimesefff7062013-11-21 03:35:02 +010028def data_file(*name):
29 return os.path.join(os.path.dirname(__file__), *name)
Antoine Pitrou152efa22010-05-16 18:19:27 +000030
Antoine Pitrou81564092010-10-08 23:06:24 +000031# The custom key and certificate files used in test_ssl are generated
32# using Lib/test/make_ssl_certs.py.
33# Other certificates are simply fetched from the Internet servers they
34# are meant to authenticate.
35
Antoine Pitrou152efa22010-05-16 18:19:27 +000036CERTFILE = data_file("keycert.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000037BYTES_CERTFILE = os.fsencode(CERTFILE)
Antoine Pitrou152efa22010-05-16 18:19:27 +000038ONLYCERT = data_file("ssl_cert.pem")
39ONLYKEY = data_file("ssl_key.pem")
Victor Stinner313a1202010-06-11 23:56:51 +000040BYTES_ONLYCERT = os.fsencode(ONLYCERT)
41BYTES_ONLYKEY = os.fsencode(ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +020042CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
43ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
44KEY_PASSWORD = "somepass"
Antoine Pitrou152efa22010-05-16 18:19:27 +000045CAPATH = data_file("capath")
Victor Stinner313a1202010-06-11 23:56:51 +000046BYTES_CAPATH = os.fsencode(CAPATH)
Christian Heimesefff7062013-11-21 03:35:02 +010047CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
48CAFILE_CACERT = data_file("capath", "5ed36f99.0")
49
Antoine Pitrou152efa22010-05-16 18:19:27 +000050
Christian Heimes22587792013-11-21 23:56:13 +010051# empty CRL
52CRLFILE = data_file("revocation.crl")
53
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010054# Two keys and certs signed by the same CA (for SNI tests)
55SIGNED_CERTFILE = data_file("keycert3.pem")
56SIGNED_CERTFILE2 = data_file("keycert4.pem")
57SIGNING_CA = data_file("pycacert.pem")
58
Antoine Pitrou152efa22010-05-16 18:19:27 +000059SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
60
61EMPTYCERT = data_file("nullcert.pem")
62BADCERT = data_file("badcert.pem")
63WRONGCERT = data_file("XXXnonexisting.pem")
64BADKEY = data_file("badkey.pem")
Antoine Pitroud8c347a2011-10-01 19:20:25 +020065NOKIACERT = data_file("nokia.pem")
Christian Heimes824f7f32013-08-17 00:54:47 +020066NULLBYTECERT = data_file("nullbytecert.pem")
Antoine Pitrou152efa22010-05-16 18:19:27 +000067
Antoine Pitrou0e576f12011-12-22 10:03:38 +010068DHFILE = data_file("dh512.pem")
69BYTES_DHFILE = os.fsencode(DHFILE)
Thomas Woutersed03b412007-08-28 21:37:11 +000070
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010071
Thomas Woutersed03b412007-08-28 21:37:11 +000072def handle_error(prefix):
73 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersonee8712c2008-05-20 21:35:26 +000074 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +000075 sys.stdout.write(prefix + exc_format)
Thomas Woutersed03b412007-08-28 21:37:11 +000076
Antoine Pitroub5218772010-05-21 09:56:06 +000077def can_clear_options():
78 # 0.9.8m or higher
Antoine Pitroub9ac25d2011-07-08 18:47:06 +020079 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
Antoine Pitroub5218772010-05-21 09:56:06 +000080
81def no_sslv2_implies_sslv3_hello():
82 # 0.9.7h or higher
83 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
84
Christian Heimes2427b502013-11-23 11:24:32 +010085def have_verify_flags():
86 # 0.9.8 or higher
87 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
88
Christian Heimes9424bb42013-06-17 15:32:57 +020089def asn1time(cert_time):
90 # Some versions of OpenSSL ignore seconds, see #18207
91 # 0.9.8.i
92 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
93 fmt = "%b %d %H:%M:%S %Y GMT"
94 dt = datetime.datetime.strptime(cert_time, fmt)
95 dt = dt.replace(second=0)
96 cert_time = dt.strftime(fmt)
97 # %d adds leading zero but ASN1_TIME_print() uses leading space
98 if cert_time[4] == "0":
99 cert_time = cert_time[:4] + " " + cert_time[5:]
100
101 return cert_time
Thomas Woutersed03b412007-08-28 21:37:11 +0000102
Antoine Pitrou23df4832010-08-04 17:14:06 +0000103# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
104def skip_if_broken_ubuntu_ssl(func):
Victor Stinner3de49192011-05-09 00:42:58 +0200105 if hasattr(ssl, 'PROTOCOL_SSLv2'):
106 @functools.wraps(func)
107 def f(*args, **kwargs):
108 try:
109 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
110 except ssl.SSLError:
111 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
112 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
113 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
114 return func(*args, **kwargs)
115 return f
116 else:
117 return func
Antoine Pitrou23df4832010-08-04 17:14:06 +0000118
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100119needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
120
Antoine Pitrou23df4832010-08-04 17:14:06 +0000121
Antoine Pitrou152efa22010-05-16 18:19:27 +0000122class BasicSocketTests(unittest.TestCase):
Thomas Woutersed03b412007-08-28 21:37:11 +0000123
Antoine Pitrou480a1242010-04-28 21:37:09 +0000124 def test_constants(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000125 ssl.CERT_NONE
126 ssl.CERT_OPTIONAL
127 ssl.CERT_REQUIRED
Antoine Pitrou6db49442011-12-19 13:27:11 +0100128 ssl.OP_CIPHER_SERVER_PREFERENCE
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100129 ssl.OP_SINGLE_DH_USE
Antoine Pitrouc135fa42012-02-19 21:22:39 +0100130 if ssl.HAS_ECDH:
131 ssl.OP_SINGLE_ECDH_USE
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +0100132 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
133 ssl.OP_NO_COMPRESSION
Antoine Pitroud5323212010-10-22 18:19:07 +0000134 self.assertIn(ssl.HAS_SNI, {True, False})
Antoine Pitrou501da612011-12-21 09:27:41 +0100135 self.assertIn(ssl.HAS_ECDH, {True, False})
Thomas Woutersed03b412007-08-28 21:37:11 +0000136
Antoine Pitrou480a1242010-04-28 21:37:09 +0000137 def test_random(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000138 v = ssl.RAND_status()
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000139 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000140 sys.stdout.write("\n RAND_status is %d (%s)\n"
141 % (v, (v and "sufficient randomness") or
142 "insufficient randomness"))
Victor Stinner99c8b162011-05-24 12:05:19 +0200143
144 data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
145 self.assertEqual(len(data), 16)
146 self.assertEqual(is_cryptographic, v == 1)
147 if v:
148 data = ssl.RAND_bytes(16)
149 self.assertEqual(len(data), 16)
Victor Stinner2e2baa92011-05-25 11:15:16 +0200150 else:
151 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
Victor Stinner99c8b162011-05-24 12:05:19 +0200152
Victor Stinner1e81a392013-12-19 16:47:04 +0100153 # negative num is invalid
154 self.assertRaises(ValueError, ssl.RAND_bytes, -5)
155 self.assertRaises(ValueError, ssl.RAND_pseudo_bytes, -5)
156
Jesus Ceac8754a12012-09-11 02:00:58 +0200157 self.assertRaises(TypeError, ssl.RAND_egd, 1)
158 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000159 ssl.RAND_add("this is a random string", 75.0)
Thomas Woutersed03b412007-08-28 21:37:11 +0000160
Christian Heimesf77b4b22013-08-21 13:26:05 +0200161 @unittest.skipUnless(os.name == 'posix', 'requires posix')
162 def test_random_fork(self):
163 status = ssl.RAND_status()
164 if not status:
165 self.fail("OpenSSL's PRNG has insufficient randomness")
166
167 rfd, wfd = os.pipe()
168 pid = os.fork()
169 if pid == 0:
170 try:
171 os.close(rfd)
172 child_random = ssl.RAND_pseudo_bytes(16)[0]
173 self.assertEqual(len(child_random), 16)
174 os.write(wfd, child_random)
175 os.close(wfd)
176 except BaseException:
177 os._exit(1)
178 else:
179 os._exit(0)
180 else:
181 os.close(wfd)
182 self.addCleanup(os.close, rfd)
183 _, status = os.waitpid(pid, 0)
184 self.assertEqual(status, 0)
185
186 child_random = os.read(rfd, 16)
187 self.assertEqual(len(child_random), 16)
188 parent_random = ssl.RAND_pseudo_bytes(16)[0]
189 self.assertEqual(len(parent_random), 16)
190
191 self.assertNotEqual(child_random, parent_random)
192
Antoine Pitrou480a1242010-04-28 21:37:09 +0000193 def test_parse_cert(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000194 # note that this uses an 'unofficial' function in _ssl.c,
195 # provided solely for this test, to exercise the certificate
196 # parsing code
Antoine Pitroufb046912010-11-09 20:21:19 +0000197 p = ssl._ssl._test_decode_cert(CERTFILE)
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000198 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000199 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200200 self.assertEqual(p['issuer'],
201 ((('countryName', 'XY'),),
202 (('localityName', 'Castle Anthrax'),),
203 (('organizationName', 'Python Software Foundation'),),
204 (('commonName', 'localhost'),))
205 )
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100206 # Note the next three asserts will fail if the keys are regenerated
Christian Heimes9424bb42013-06-17 15:32:57 +0200207 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
208 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
Antoine Pitroud8c347a2011-10-01 19:20:25 +0200209 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
210 self.assertEqual(p['subject'],
211 ((('countryName', 'XY'),),
212 (('localityName', 'Castle Anthrax'),),
213 (('organizationName', 'Python Software Foundation'),),
214 (('commonName', 'localhost'),))
215 )
216 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
217 # Issue #13034: the subjectAltName in some certificates
218 # (notably projects.developer.nokia.com:443) wasn't parsed
219 p = ssl._ssl._test_decode_cert(NOKIACERT)
220 if support.verbose:
221 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
222 self.assertEqual(p['subjectAltName'],
223 (('DNS', 'projects.developer.nokia.com'),
224 ('DNS', 'projects.forum.nokia.com'))
225 )
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100226 # extra OCSP and AIA fields
227 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
228 self.assertEqual(p['caIssuers'],
229 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
230 self.assertEqual(p['crlDistributionPoints'],
231 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Thomas Woutersed03b412007-08-28 21:37:11 +0000232
Christian Heimes824f7f32013-08-17 00:54:47 +0200233 def test_parse_cert_CVE_2013_4238(self):
234 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
235 if support.verbose:
236 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
237 subject = ((('countryName', 'US'),),
238 (('stateOrProvinceName', 'Oregon'),),
239 (('localityName', 'Beaverton'),),
240 (('organizationName', 'Python Software Foundation'),),
241 (('organizationalUnitName', 'Python Core Development'),),
242 (('commonName', 'null.python.org\x00example.org'),),
243 (('emailAddress', 'python-dev@python.org'),))
244 self.assertEqual(p['subject'], subject)
245 self.assertEqual(p['issuer'], subject)
Christian Heimes157c9832013-08-25 14:12:41 +0200246 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
247 san = (('DNS', 'altnull.python.org\x00example.com'),
248 ('email', 'null@python.org\x00user@example.org'),
249 ('URI', 'http://null.python.org\x00http://example.org'),
250 ('IP Address', '192.0.2.1'),
251 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
252 else:
253 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
254 san = (('DNS', 'altnull.python.org\x00example.com'),
255 ('email', 'null@python.org\x00user@example.org'),
256 ('URI', 'http://null.python.org\x00http://example.org'),
257 ('IP Address', '192.0.2.1'),
258 ('IP Address', '<invalid>'))
259
260 self.assertEqual(p['subjectAltName'], san)
Christian Heimes824f7f32013-08-17 00:54:47 +0200261
Antoine Pitrou480a1242010-04-28 21:37:09 +0000262 def test_DER_to_PEM(self):
263 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
264 pem = f.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000265 d1 = ssl.PEM_cert_to_DER_cert(pem)
266 p2 = ssl.DER_cert_to_PEM_cert(d1)
267 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitrou18c913e2010-04-27 10:59:39 +0000268 self.assertEqual(d1, d2)
Antoine Pitrou9bfbe612010-04-27 22:08:08 +0000269 if not p2.startswith(ssl.PEM_HEADER + '\n'):
270 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
271 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
272 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +0000273
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000274 def test_openssl_version(self):
275 n = ssl.OPENSSL_VERSION_NUMBER
276 t = ssl.OPENSSL_VERSION_INFO
277 s = ssl.OPENSSL_VERSION
278 self.assertIsInstance(n, int)
279 self.assertIsInstance(t, tuple)
280 self.assertIsInstance(s, str)
281 # Some sanity checks follow
282 # >= 0.9
283 self.assertGreaterEqual(n, 0x900000)
284 # < 2.0
285 self.assertLess(n, 0x20000000)
286 major, minor, fix, patch, status = t
287 self.assertGreaterEqual(major, 0)
288 self.assertLess(major, 2)
289 self.assertGreaterEqual(minor, 0)
290 self.assertLess(minor, 256)
291 self.assertGreaterEqual(fix, 0)
292 self.assertLess(fix, 256)
293 self.assertGreaterEqual(patch, 0)
294 self.assertLessEqual(patch, 26)
295 self.assertGreaterEqual(status, 0)
296 self.assertLessEqual(status, 15)
297 # Version string as returned by OpenSSL, the format might change
298 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
299 (s, t))
300
Antoine Pitrou9d543662010-04-23 23:10:32 +0000301 @support.cpython_only
302 def test_refcycle(self):
303 # Issue #7943: an SSL object doesn't create reference cycles with
304 # itself.
305 s = socket.socket(socket.AF_INET)
306 ss = ssl.wrap_socket(s)
307 wr = weakref.ref(ss)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100308 with support.check_warnings(("", ResourceWarning)):
309 del ss
310 self.assertEqual(wr(), None)
Antoine Pitrou9d543662010-04-23 23:10:32 +0000311
Antoine Pitroua468adc2010-09-14 14:43:44 +0000312 def test_wrapped_unconnected(self):
313 # Methods on an unconnected SSLSocket propagate the original
Andrew Svetlov0832af62012-12-18 23:10:48 +0200314 # OSError raise by the underlying socket object.
Antoine Pitroua468adc2010-09-14 14:43:44 +0000315 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100316 with ssl.wrap_socket(s) as ss:
Antoine Pitroue9bb4732013-01-12 21:56:56 +0100317 self.assertRaises(OSError, ss.recv, 1)
318 self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
319 self.assertRaises(OSError, ss.recvfrom, 1)
320 self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
321 self.assertRaises(OSError, ss.send, b'x')
322 self.assertRaises(OSError, ss.sendto, b'x', ('0.0.0.0', 0))
Antoine Pitroua468adc2010-09-14 14:43:44 +0000323
Antoine Pitrou40f08742010-04-24 22:04:40 +0000324 def test_timeout(self):
325 # Issue #8524: when creating an SSL socket, the timeout of the
326 # original socket should be retained.
327 for timeout in (None, 0.0, 5.0):
328 s = socket.socket(socket.AF_INET)
329 s.settimeout(timeout)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100330 with ssl.wrap_socket(s) as ss:
331 self.assertEqual(timeout, ss.gettimeout())
Antoine Pitrou40f08742010-04-24 22:04:40 +0000332
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000333 def test_errors(self):
334 sock = socket.socket()
Ezio Melottied3a7d22010-12-01 02:32:32 +0000335 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000336 "certfile must be specified",
337 ssl.wrap_socket, sock, keyfile=CERTFILE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000338 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000339 "certfile must be specified for server-side operations",
340 ssl.wrap_socket, sock, server_side=True)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000341 self.assertRaisesRegex(ValueError,
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000342 "certfile must be specified for server-side operations",
343 ssl.wrap_socket, sock, server_side=True, certfile="")
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100344 with ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) as s:
345 self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
346 s.connect, (HOST, 8080))
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200347 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000348 with socket.socket() as sock:
349 ssl.wrap_socket(sock, certfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000350 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200351 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000352 with socket.socket() as sock:
353 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
Giampaolo Rodolà8b7da622010-08-30 18:28:05 +0000354 self.assertEqual(cm.exception.errno, errno.ENOENT)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200355 with self.assertRaises(OSError) as cm:
Antoine Pitroud2eca372010-10-29 23:41:37 +0000356 with socket.socket() as sock:
357 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000358 self.assertEqual(cm.exception.errno, errno.ENOENT)
Giampaolo Rodolà745ab382010-08-29 19:25:49 +0000359
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000360 def test_match_hostname(self):
361 def ok(cert, hostname):
362 ssl.match_hostname(cert, hostname)
363 def fail(cert, hostname):
364 self.assertRaises(ssl.CertificateError,
365 ssl.match_hostname, cert, hostname)
366
367 cert = {'subject': ((('commonName', 'example.com'),),)}
368 ok(cert, 'example.com')
369 ok(cert, 'ExAmple.cOm')
370 fail(cert, 'www.example.com')
371 fail(cert, '.example.com')
372 fail(cert, 'example.org')
373 fail(cert, 'exampleXcom')
374
375 cert = {'subject': ((('commonName', '*.a.com'),),)}
376 ok(cert, 'foo.a.com')
377 fail(cert, 'bar.foo.a.com')
378 fail(cert, 'a.com')
379 fail(cert, 'Xa.com')
380 fail(cert, '.a.com')
381
Georg Brandl72c98d32013-10-27 07:16:53 +0100382 # only match one left-most wildcard
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000383 cert = {'subject': ((('commonName', 'f*.com'),),)}
384 ok(cert, 'foo.com')
385 ok(cert, 'f.com')
386 fail(cert, 'bar.com')
387 fail(cert, 'foo.a.com')
388 fail(cert, 'bar.foo.com')
389
Christian Heimes824f7f32013-08-17 00:54:47 +0200390 # NULL bytes are bad, CVE-2013-4073
391 cert = {'subject': ((('commonName',
392 'null.python.org\x00example.org'),),)}
393 ok(cert, 'null.python.org\x00example.org') # or raise an error?
394 fail(cert, 'example.org')
395 fail(cert, 'null.python.org')
396
Georg Brandl72c98d32013-10-27 07:16:53 +0100397 # error cases with wildcards
398 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
399 fail(cert, 'bar.foo.a.com')
400 fail(cert, 'a.com')
401 fail(cert, 'Xa.com')
402 fail(cert, '.a.com')
403
404 cert = {'subject': ((('commonName', 'a.*.com'),),)}
405 fail(cert, 'a.foo.com')
406 fail(cert, 'a..com')
407 fail(cert, 'a.com')
408
409 # wildcard doesn't match IDNA prefix 'xn--'
410 idna = 'püthon.python.org'.encode("idna").decode("ascii")
411 cert = {'subject': ((('commonName', idna),),)}
412 ok(cert, idna)
413 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
414 fail(cert, idna)
415 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
416 fail(cert, idna)
417
418 # wildcard in first fragment and IDNA A-labels in sequent fragments
419 # are supported.
420 idna = 'www*.pythön.org'.encode("idna").decode("ascii")
421 cert = {'subject': ((('commonName', idna),),)}
422 ok(cert, 'www.pythön.org'.encode("idna").decode("ascii"))
423 ok(cert, 'www1.pythön.org'.encode("idna").decode("ascii"))
424 fail(cert, 'ftp.pythön.org'.encode("idna").decode("ascii"))
425 fail(cert, 'pythön.org'.encode("idna").decode("ascii"))
426
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000427 # Slightly fake real-world example
428 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
429 'subject': ((('commonName', 'linuxfrz.org'),),),
430 'subjectAltName': (('DNS', 'linuxfr.org'),
431 ('DNS', 'linuxfr.com'),
432 ('othername', '<unsupported>'))}
433 ok(cert, 'linuxfr.org')
434 ok(cert, 'linuxfr.com')
435 # Not a "DNS" entry
436 fail(cert, '<unsupported>')
437 # When there is a subjectAltName, commonName isn't used
438 fail(cert, 'linuxfrz.org')
439
440 # A pristine real-world example
441 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
442 'subject': ((('countryName', 'US'),),
443 (('stateOrProvinceName', 'California'),),
444 (('localityName', 'Mountain View'),),
445 (('organizationName', 'Google Inc'),),
446 (('commonName', 'mail.google.com'),))}
447 ok(cert, 'mail.google.com')
448 fail(cert, 'gmail.com')
449 # Only commonName is considered
450 fail(cert, 'California')
451
452 # Neither commonName nor subjectAltName
453 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
454 'subject': ((('countryName', 'US'),),
455 (('stateOrProvinceName', 'California'),),
456 (('localityName', 'Mountain View'),),
457 (('organizationName', 'Google Inc'),))}
458 fail(cert, 'mail.google.com')
459
Antoine Pitrou1c86b442011-05-06 15:19:49 +0200460 # No DNS entry in subjectAltName but a commonName
461 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
462 'subject': ((('countryName', 'US'),),
463 (('stateOrProvinceName', 'California'),),
464 (('localityName', 'Mountain View'),),
465 (('commonName', 'mail.google.com'),)),
466 'subjectAltName': (('othername', 'blabla'), )}
467 ok(cert, 'mail.google.com')
468
469 # No DNS entry subjectAltName and no commonName
470 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
471 'subject': ((('countryName', 'US'),),
472 (('stateOrProvinceName', 'California'),),
473 (('localityName', 'Mountain View'),),
474 (('organizationName', 'Google Inc'),)),
475 'subjectAltName': (('othername', 'blabla'),)}
476 fail(cert, 'google.com')
477
Antoine Pitrou59fdd672010-10-08 10:37:08 +0000478 # Empty cert / no cert
479 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
480 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
481
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200482 # Issue #17980: avoid denials of service by refusing more than one
483 # wildcard per fragment.
484 cert = {'subject': ((('commonName', 'a*b.com'),),)}
485 ok(cert, 'axxb.com')
486 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
Georg Brandl72c98d32013-10-27 07:16:53 +0100487 fail(cert, 'axxb.com')
Antoine Pitrou636f93c2013-05-18 17:56:42 +0200488 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
489 with self.assertRaises(ssl.CertificateError) as cm:
490 ssl.match_hostname(cert, 'axxbxxc.com')
491 self.assertIn("too many wildcards", str(cm.exception))
492
Antoine Pitroud5323212010-10-22 18:19:07 +0000493 def test_server_side(self):
494 # server_hostname doesn't work for server sockets
495 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
Antoine Pitroud2eca372010-10-29 23:41:37 +0000496 with socket.socket() as sock:
497 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
498 server_hostname="some.hostname")
Antoine Pitrou04f6a322010-04-05 21:40:07 +0000499
Antoine Pitroud6494802011-07-21 01:11:30 +0200500 def test_unknown_channel_binding(self):
501 # should raise ValueError for unknown type
502 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100503 with ssl.wrap_socket(s) as ss:
504 with self.assertRaises(ValueError):
505 ss.get_channel_binding("unknown-type")
Antoine Pitroud6494802011-07-21 01:11:30 +0200506
507 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
508 "'tls-unique' channel binding not available")
509 def test_tls_unique_channel_binding(self):
510 # unconnected should return None for known type
511 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100512 with ssl.wrap_socket(s) as ss:
513 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200514 # the same for server-side
515 s = socket.socket(socket.AF_INET)
Antoine Pitroue1ceb502013-01-12 21:54:44 +0100516 with ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) as ss:
517 self.assertIsNone(ss.get_channel_binding("tls-unique"))
Antoine Pitroud6494802011-07-21 01:11:30 +0200518
Benjamin Peterson36f7b972013-01-10 14:16:20 -0600519 def test_dealloc_warn(self):
520 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
521 r = repr(ss)
522 with self.assertWarns(ResourceWarning) as cm:
523 ss = None
524 support.gc_collect()
525 self.assertIn(r, str(cm.warning.args[0]))
526
Christian Heimes6d7ad132013-06-09 18:02:55 +0200527 def test_get_default_verify_paths(self):
528 paths = ssl.get_default_verify_paths()
529 self.assertEqual(len(paths), 6)
530 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
531
532 with support.EnvironmentVarGuard() as env:
533 env["SSL_CERT_DIR"] = CAPATH
534 env["SSL_CERT_FILE"] = CERTFILE
535 paths = ssl.get_default_verify_paths()
536 self.assertEqual(paths.cafile, CERTFILE)
537 self.assertEqual(paths.capath, CAPATH)
538
Christian Heimes44109d72013-11-22 01:51:30 +0100539 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
540 def test_enum_certificates(self):
541 self.assertTrue(ssl.enum_certificates("CA"))
542 self.assertTrue(ssl.enum_certificates("ROOT"))
543
544 self.assertRaises(TypeError, ssl.enum_certificates)
545 self.assertRaises(WindowsError, ssl.enum_certificates, "")
546
Christian Heimesc2d65e12013-11-22 16:13:55 +0100547 trust_oids = set()
548 for storename in ("CA", "ROOT"):
549 store = ssl.enum_certificates(storename)
550 self.assertIsInstance(store, list)
551 for element in store:
552 self.assertIsInstance(element, tuple)
553 self.assertEqual(len(element), 3)
554 cert, enc, trust = element
555 self.assertIsInstance(cert, bytes)
556 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
557 self.assertIsInstance(trust, (set, bool))
558 if isinstance(trust, set):
559 trust_oids.update(trust)
Christian Heimes44109d72013-11-22 01:51:30 +0100560
561 serverAuth = "1.3.6.1.5.5.7.3.1"
Christian Heimesc2d65e12013-11-22 16:13:55 +0100562 self.assertIn(serverAuth, trust_oids)
Christian Heimes6d7ad132013-06-09 18:02:55 +0200563
Christian Heimes46bebee2013-06-09 19:03:31 +0200564 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
Christian Heimes44109d72013-11-22 01:51:30 +0100565 def test_enum_crls(self):
566 self.assertTrue(ssl.enum_crls("CA"))
567 self.assertRaises(TypeError, ssl.enum_crls)
568 self.assertRaises(WindowsError, ssl.enum_crls, "")
Christian Heimes46bebee2013-06-09 19:03:31 +0200569
Christian Heimes44109d72013-11-22 01:51:30 +0100570 crls = ssl.enum_crls("CA")
571 self.assertIsInstance(crls, list)
572 for element in crls:
573 self.assertIsInstance(element, tuple)
574 self.assertEqual(len(element), 2)
575 self.assertIsInstance(element[0], bytes)
576 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
Christian Heimes46bebee2013-06-09 19:03:31 +0200577
Christian Heimes46bebee2013-06-09 19:03:31 +0200578
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100579 def test_asn1object(self):
580 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
581 '1.3.6.1.5.5.7.3.1')
582
583 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
584 self.assertEqual(val, expected)
585 self.assertEqual(val.nid, 129)
586 self.assertEqual(val.shortname, 'serverAuth')
587 self.assertEqual(val.longname, 'TLS Web Server Authentication')
588 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
589 self.assertIsInstance(val, ssl._ASN1Object)
590 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
591
592 val = ssl._ASN1Object.fromnid(129)
593 self.assertEqual(val, expected)
594 self.assertIsInstance(val, ssl._ASN1Object)
595 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100596 with self.assertRaisesRegex(ValueError, "unknown NID 100000"):
597 ssl._ASN1Object.fromnid(100000)
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100598 for i in range(1000):
599 try:
600 obj = ssl._ASN1Object.fromnid(i)
601 except ValueError:
602 pass
603 else:
604 self.assertIsInstance(obj.nid, int)
605 self.assertIsInstance(obj.shortname, str)
606 self.assertIsInstance(obj.longname, str)
607 self.assertIsInstance(obj.oid, (str, type(None)))
608
609 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
610 self.assertEqual(val, expected)
611 self.assertIsInstance(val, ssl._ASN1Object)
612 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
613 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
614 expected)
Christian Heimes5398e1a2013-11-22 16:20:53 +0100615 with self.assertRaisesRegex(ValueError, "unknown object 'serverauth'"):
616 ssl._ASN1Object.fromname('serverauth')
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100617
Christian Heimes72d28502013-11-23 13:56:58 +0100618 def test_purpose_enum(self):
619 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
620 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
621 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
622 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
623 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
624 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
625 '1.3.6.1.5.5.7.3.1')
626
627 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
628 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
629 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
630 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
631 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
632 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
633 '1.3.6.1.5.5.7.3.2')
634
Antoine Pitrou3e86ba42013-12-28 17:26:33 +0100635 def test_unsupported_dtls(self):
636 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
637 self.addCleanup(s.close)
638 with self.assertRaises(NotImplementedError) as cx:
639 ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
640 self.assertEqual(str(cx.exception), "only stream sockets are supported")
641 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
642 with self.assertRaises(NotImplementedError) as cx:
643 ctx.wrap_socket(s)
644 self.assertEqual(str(cx.exception), "only stream sockets are supported")
645
Christian Heimesa6bc95a2013-11-17 19:59:14 +0100646
Antoine Pitrou152efa22010-05-16 18:19:27 +0000647class ContextTests(unittest.TestCase):
648
Antoine Pitrou23df4832010-08-04 17:14:06 +0000649 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000650 def test_constructor(self):
Antoine Pitrou2463e5f2013-03-28 22:24:43 +0100651 for protocol in PROTOCOLS:
652 ssl.SSLContext(protocol)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000653 self.assertRaises(TypeError, ssl.SSLContext)
654 self.assertRaises(ValueError, ssl.SSLContext, -1)
655 self.assertRaises(ValueError, ssl.SSLContext, 42)
656
Antoine Pitrou23df4832010-08-04 17:14:06 +0000657 @skip_if_broken_ubuntu_ssl
Antoine Pitrou152efa22010-05-16 18:19:27 +0000658 def test_protocol(self):
659 for proto in PROTOCOLS:
660 ctx = ssl.SSLContext(proto)
661 self.assertEqual(ctx.protocol, proto)
662
663 def test_ciphers(self):
664 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
665 ctx.set_ciphers("ALL")
666 ctx.set_ciphers("DEFAULT")
Ezio Melottied3a7d22010-12-01 02:32:32 +0000667 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitrou30474062010-05-16 23:46:26 +0000668 ctx.set_ciphers("^$:,;?*'dorothyx")
Antoine Pitrou152efa22010-05-16 18:19:27 +0000669
Antoine Pitrou23df4832010-08-04 17:14:06 +0000670 @skip_if_broken_ubuntu_ssl
Antoine Pitroub5218772010-05-21 09:56:06 +0000671 def test_options(self):
672 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +0100673 # OP_ALL | OP_NO_SSLv2 is the default value
Antoine Pitroub5218772010-05-21 09:56:06 +0000674 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
675 ctx.options)
676 ctx.options |= ssl.OP_NO_SSLv3
677 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
678 ctx.options)
679 if can_clear_options():
680 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
681 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
682 ctx.options)
683 ctx.options = 0
684 self.assertEqual(0, ctx.options)
685 else:
686 with self.assertRaises(ValueError):
687 ctx.options = 0
688
Christian Heimes22587792013-11-21 23:56:13 +0100689 def test_verify_mode(self):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000690 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
691 # Default value
692 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
693 ctx.verify_mode = ssl.CERT_OPTIONAL
694 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
695 ctx.verify_mode = ssl.CERT_REQUIRED
696 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
697 ctx.verify_mode = ssl.CERT_NONE
698 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
699 with self.assertRaises(TypeError):
700 ctx.verify_mode = None
701 with self.assertRaises(ValueError):
702 ctx.verify_mode = 42
703
Christian Heimes2427b502013-11-23 11:24:32 +0100704 @unittest.skipUnless(have_verify_flags(),
705 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +0100706 def test_verify_flags(self):
707 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
708 # default value by OpenSSL
709 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
710 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
711 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
712 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
713 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
714 ctx.verify_flags = ssl.VERIFY_DEFAULT
715 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
716 # supports any value
717 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
718 self.assertEqual(ctx.verify_flags,
719 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
720 with self.assertRaises(TypeError):
721 ctx.verify_flags = None
722
Antoine Pitrou152efa22010-05-16 18:19:27 +0000723 def test_load_cert_chain(self):
724 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
725 # Combined key and cert in a single file
726 ctx.load_cert_chain(CERTFILE)
727 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
728 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200729 with self.assertRaises(OSError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000730 ctx.load_cert_chain(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000731 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000732 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000733 ctx.load_cert_chain(BADCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000734 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000735 ctx.load_cert_chain(EMPTYCERT)
736 # Separate key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000737 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000738 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
739 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
740 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000741 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000742 ctx.load_cert_chain(ONLYCERT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000743 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000744 ctx.load_cert_chain(ONLYKEY)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000745 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000746 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
747 # Mismatching key and cert
Antoine Pitroud0919502010-05-17 10:30:00 +0000748 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000749 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
Antoine Pitrou81564092010-10-08 23:06:24 +0000750 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
Antoine Pitrou4fd1e6a2011-08-25 14:39:44 +0200751 # Password protected key and cert
752 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
753 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
754 ctx.load_cert_chain(CERTFILE_PROTECTED,
755 password=bytearray(KEY_PASSWORD.encode()))
756 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
757 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
758 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
759 bytearray(KEY_PASSWORD.encode()))
760 with self.assertRaisesRegex(TypeError, "should be a string"):
761 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
762 with self.assertRaises(ssl.SSLError):
763 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
764 with self.assertRaisesRegex(ValueError, "cannot be longer"):
765 # openssl has a fixed limit on the password buffer.
766 # PEM_BUFSIZE is generally set to 1kb.
767 # Return a string larger than this.
768 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
769 # Password callback
770 def getpass_unicode():
771 return KEY_PASSWORD
772 def getpass_bytes():
773 return KEY_PASSWORD.encode()
774 def getpass_bytearray():
775 return bytearray(KEY_PASSWORD.encode())
776 def getpass_badpass():
777 return "badpass"
778 def getpass_huge():
779 return b'a' * (1024 * 1024)
780 def getpass_bad_type():
781 return 9
782 def getpass_exception():
783 raise Exception('getpass error')
784 class GetPassCallable:
785 def __call__(self):
786 return KEY_PASSWORD
787 def getpass(self):
788 return KEY_PASSWORD
789 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
790 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
791 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
792 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
793 ctx.load_cert_chain(CERTFILE_PROTECTED,
794 password=GetPassCallable().getpass)
795 with self.assertRaises(ssl.SSLError):
796 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
797 with self.assertRaisesRegex(ValueError, "cannot be longer"):
798 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
799 with self.assertRaisesRegex(TypeError, "must return a string"):
800 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
801 with self.assertRaisesRegex(Exception, "getpass error"):
802 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
803 # Make sure the password function isn't called if it isn't needed
804 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
Antoine Pitrou152efa22010-05-16 18:19:27 +0000805
806 def test_load_verify_locations(self):
807 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
808 ctx.load_verify_locations(CERTFILE)
809 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
810 ctx.load_verify_locations(BYTES_CERTFILE)
811 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
812 self.assertRaises(TypeError, ctx.load_verify_locations)
Christian Heimesefff7062013-11-21 03:35:02 +0100813 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +0200814 with self.assertRaises(OSError) as cm:
Antoine Pitrou152efa22010-05-16 18:19:27 +0000815 ctx.load_verify_locations(WRONGCERT)
Giampaolo Rodolà4a656eb2010-08-29 22:50:39 +0000816 self.assertEqual(cm.exception.errno, errno.ENOENT)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000817 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
Antoine Pitrou152efa22010-05-16 18:19:27 +0000818 ctx.load_verify_locations(BADCERT)
819 ctx.load_verify_locations(CERTFILE, CAPATH)
820 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
821
Victor Stinner80f75e62011-01-29 11:31:20 +0000822 # Issue #10989: crash if the second argument type is invalid
823 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
824
Christian Heimesefff7062013-11-21 03:35:02 +0100825 def test_load_verify_cadata(self):
826 # test cadata
827 with open(CAFILE_CACERT) as f:
828 cacert_pem = f.read()
829 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
830 with open(CAFILE_NEURONIO) as f:
831 neuronio_pem = f.read()
832 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
833
834 # test PEM
835 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
836 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
837 ctx.load_verify_locations(cadata=cacert_pem)
838 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
839 ctx.load_verify_locations(cadata=neuronio_pem)
840 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
841 # cert already in hash table
842 ctx.load_verify_locations(cadata=neuronio_pem)
843 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
844
845 # combined
846 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
847 combined = "\n".join((cacert_pem, neuronio_pem))
848 ctx.load_verify_locations(cadata=combined)
849 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
850
851 # with junk around the certs
852 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
853 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
854 neuronio_pem, "tail"]
855 ctx.load_verify_locations(cadata="\n".join(combined))
856 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
857
858 # test DER
859 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
860 ctx.load_verify_locations(cadata=cacert_der)
861 ctx.load_verify_locations(cadata=neuronio_der)
862 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
863 # cert already in hash table
864 ctx.load_verify_locations(cadata=cacert_der)
865 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
866
867 # combined
868 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
869 combined = b"".join((cacert_der, neuronio_der))
870 ctx.load_verify_locations(cadata=combined)
871 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
872
873 # error cases
874 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
875 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
876
877 with self.assertRaisesRegex(ssl.SSLError, "no start line"):
878 ctx.load_verify_locations(cadata="broken")
879 with self.assertRaisesRegex(ssl.SSLError, "not enough data"):
880 ctx.load_verify_locations(cadata=b"broken")
881
882
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100883 def test_load_dh_params(self):
884 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
885 ctx.load_dh_params(DHFILE)
886 if os.name != 'nt':
887 ctx.load_dh_params(BYTES_DHFILE)
888 self.assertRaises(TypeError, ctx.load_dh_params)
889 self.assertRaises(TypeError, ctx.load_dh_params, None)
890 with self.assertRaises(FileNotFoundError) as cm:
891 ctx.load_dh_params(WRONGCERT)
892 self.assertEqual(cm.exception.errno, errno.ENOENT)
Antoine Pitrou3b36fb12012-06-22 21:11:52 +0200893 with self.assertRaises(ssl.SSLError) as cm:
Antoine Pitrou0e576f12011-12-22 10:03:38 +0100894 ctx.load_dh_params(CERTFILE)
895
Antoine Pitroueb585ad2010-10-22 18:24:20 +0000896 @skip_if_broken_ubuntu_ssl
Antoine Pitroub0182c82010-10-12 20:09:02 +0000897 def test_session_stats(self):
898 for proto in PROTOCOLS:
899 ctx = ssl.SSLContext(proto)
900 self.assertEqual(ctx.session_stats(), {
901 'number': 0,
902 'connect': 0,
903 'connect_good': 0,
904 'connect_renegotiate': 0,
905 'accept': 0,
906 'accept_good': 0,
907 'accept_renegotiate': 0,
908 'hits': 0,
909 'misses': 0,
910 'timeouts': 0,
911 'cache_full': 0,
912 })
913
Antoine Pitrou664c2d12010-11-17 20:29:42 +0000914 def test_set_default_verify_paths(self):
915 # There's not much we can do to test that it acts as expected,
916 # so just check it doesn't crash or raise an exception.
917 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
918 ctx.set_default_verify_paths()
919
Antoine Pitrou501da612011-12-21 09:27:41 +0100920 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
Antoine Pitrou923df6f2011-12-19 17:16:51 +0100921 def test_set_ecdh_curve(self):
922 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
923 ctx.set_ecdh_curve("prime256v1")
924 ctx.set_ecdh_curve(b"prime256v1")
925 self.assertRaises(TypeError, ctx.set_ecdh_curve)
926 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
927 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
928 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
929
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100930 @needs_sni
931 def test_sni_callback(self):
932 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
933
934 # set_servername_callback expects a callable, or None
935 self.assertRaises(TypeError, ctx.set_servername_callback)
936 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
937 self.assertRaises(TypeError, ctx.set_servername_callback, "")
938 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
939
940 def dummycallback(sock, servername, ctx):
941 pass
942 ctx.set_servername_callback(None)
943 ctx.set_servername_callback(dummycallback)
944
945 @needs_sni
946 def test_sni_callback_refcycle(self):
947 # Reference cycles through the servername callback are detected
948 # and cleared.
949 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
950 def dummycallback(sock, servername, ctx, cycle=ctx):
951 pass
952 ctx.set_servername_callback(dummycallback)
953 wr = weakref.ref(ctx)
954 del ctx, dummycallback
955 gc.collect()
956 self.assertIs(wr(), None)
957
Christian Heimes9a5395a2013-06-17 15:44:12 +0200958 def test_cert_store_stats(self):
959 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
960 self.assertEqual(ctx.cert_store_stats(),
961 {'x509_ca': 0, 'crl': 0, 'x509': 0})
962 ctx.load_cert_chain(CERTFILE)
963 self.assertEqual(ctx.cert_store_stats(),
964 {'x509_ca': 0, 'crl': 0, 'x509': 0})
965 ctx.load_verify_locations(CERTFILE)
966 self.assertEqual(ctx.cert_store_stats(),
967 {'x509_ca': 0, 'crl': 0, 'x509': 1})
968 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
969 self.assertEqual(ctx.cert_store_stats(),
970 {'x509_ca': 1, 'crl': 0, 'x509': 2})
971
972 def test_get_ca_certs(self):
973 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
974 self.assertEqual(ctx.get_ca_certs(), [])
975 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
976 ctx.load_verify_locations(CERTFILE)
977 self.assertEqual(ctx.get_ca_certs(), [])
978 # but SVN_PYTHON_ORG_ROOT_CERT is a CA cert
979 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
980 self.assertEqual(ctx.get_ca_certs(),
981 [{'issuer': ((('organizationName', 'Root CA'),),
982 (('organizationalUnitName', 'http://www.cacert.org'),),
983 (('commonName', 'CA Cert Signing Authority'),),
984 (('emailAddress', 'support@cacert.org'),)),
985 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
986 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
987 'serialNumber': '00',
Christian Heimesbd3a7f92013-11-21 03:40:15 +0100988 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
Christian Heimes9a5395a2013-06-17 15:44:12 +0200989 'subject': ((('organizationName', 'Root CA'),),
990 (('organizationalUnitName', 'http://www.cacert.org'),),
991 (('commonName', 'CA Cert Signing Authority'),),
992 (('emailAddress', 'support@cacert.org'),)),
993 'version': 3}])
994
995 with open(SVN_PYTHON_ORG_ROOT_CERT) as f:
996 pem = f.read()
997 der = ssl.PEM_cert_to_DER_cert(pem)
998 self.assertEqual(ctx.get_ca_certs(True), [der])
999
Christian Heimes72d28502013-11-23 13:56:58 +01001000 def test_load_default_certs(self):
1001 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1002 ctx.load_default_certs()
1003
1004 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1005 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1006 ctx.load_default_certs()
1007
1008 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1009 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1010
1011 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1012 self.assertRaises(TypeError, ctx.load_default_certs, None)
1013 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1014
Christian Heimes4c05b472013-11-23 15:58:30 +01001015 def test_create_default_context(self):
1016 ctx = ssl.create_default_context()
1017 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1018 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001019 self.assertTrue(ctx.check_hostname)
Christian Heimes4c05b472013-11-23 15:58:30 +01001020 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1021
1022 with open(SIGNING_CA) as f:
1023 cadata = f.read()
1024 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1025 cadata=cadata)
1026 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1027 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1028 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1029
1030 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
1031 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1032 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1033 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1034
Christian Heimes67986f92013-11-23 22:43:47 +01001035 def test__create_stdlib_context(self):
1036 ctx = ssl._create_stdlib_context()
1037 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1038 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
Christian Heimes1aa9a752013-12-02 02:41:19 +01001039 self.assertFalse(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001040 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1041
1042 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1043 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1044 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1045 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1046
1047 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
Christian Heimesa02c69a2013-12-02 20:59:28 +01001048 cert_reqs=ssl.CERT_REQUIRED,
1049 check_hostname=True)
Christian Heimes67986f92013-11-23 22:43:47 +01001050 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1051 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
Christian Heimesa02c69a2013-12-02 20:59:28 +01001052 self.assertTrue(ctx.check_hostname)
Christian Heimes67986f92013-11-23 22:43:47 +01001053 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1054
1055 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1056 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1057 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1058 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
Christian Heimes4c05b472013-11-23 15:58:30 +01001059
Christian Heimes1aa9a752013-12-02 02:41:19 +01001060 def test_check_hostname(self):
1061 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1062 self.assertFalse(ctx.check_hostname)
1063
1064 # Requires CERT_REQUIRED or CERT_OPTIONAL
1065 with self.assertRaises(ValueError):
1066 ctx.check_hostname = True
1067 ctx.verify_mode = ssl.CERT_REQUIRED
1068 self.assertFalse(ctx.check_hostname)
1069 ctx.check_hostname = True
1070 self.assertTrue(ctx.check_hostname)
1071
1072 ctx.verify_mode = ssl.CERT_OPTIONAL
1073 ctx.check_hostname = True
1074 self.assertTrue(ctx.check_hostname)
1075
1076 # Cannot set CERT_NONE with check_hostname enabled
1077 with self.assertRaises(ValueError):
1078 ctx.verify_mode = ssl.CERT_NONE
1079 ctx.check_hostname = False
1080 self.assertFalse(ctx.check_hostname)
1081
Antoine Pitrou152efa22010-05-16 18:19:27 +00001082
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001083class SSLErrorTests(unittest.TestCase):
1084
1085 def test_str(self):
1086 # The str() of a SSLError doesn't include the errno
1087 e = ssl.SSLError(1, "foo")
1088 self.assertEqual(str(e), "foo")
1089 self.assertEqual(e.errno, 1)
1090 # Same for a subclass
1091 e = ssl.SSLZeroReturnError(1, "foo")
1092 self.assertEqual(str(e), "foo")
1093 self.assertEqual(e.errno, 1)
1094
1095 def test_lib_reason(self):
1096 # Test the library and reason attributes
1097 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1098 with self.assertRaises(ssl.SSLError) as cm:
1099 ctx.load_dh_params(CERTFILE)
1100 self.assertEqual(cm.exception.library, 'PEM')
1101 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1102 s = str(cm.exception)
1103 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1104
1105 def test_subclass(self):
1106 # Check that the appropriate SSLError subclass is raised
1107 # (this only tests one of them)
1108 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1109 with socket.socket() as s:
1110 s.bind(("127.0.0.1", 0))
1111 s.listen(5)
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001112 c = socket.socket()
1113 c.connect(s.getsockname())
1114 c.setblocking(False)
1115 with ctx.wrap_socket(c, False, do_handshake_on_connect=False) as c:
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02001116 with self.assertRaises(ssl.SSLWantReadError) as cm:
1117 c.do_handshake()
1118 s = str(cm.exception)
1119 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1120 # For compatibility
1121 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
1122
1123
Bill Janssen6e027db2007-11-15 22:23:56 +00001124class NetworkedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001125
Antoine Pitrou480a1242010-04-28 21:37:09 +00001126 def test_connect(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001127 with support.transient_internet("svn.python.org"):
1128 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1129 cert_reqs=ssl.CERT_NONE)
1130 try:
1131 s.connect(("svn.python.org", 443))
1132 self.assertEqual({}, s.getpeercert())
1133 finally:
1134 s.close()
1135
1136 # this should fail because we have no verification certs
1137 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1138 cert_reqs=ssl.CERT_REQUIRED)
Ezio Melottied3a7d22010-12-01 02:32:32 +00001139 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
1140 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001141 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001142
Antoine Pitrou350c7222010-09-09 13:31:46 +00001143 # this should succeed because we specify the root cert
1144 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1145 cert_reqs=ssl.CERT_REQUIRED,
1146 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1147 try:
1148 s.connect(("svn.python.org", 443))
1149 self.assertTrue(s.getpeercert())
1150 finally:
1151 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001152
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001153 def test_connect_ex(self):
1154 # Issue #11326: check connect_ex() implementation
1155 with support.transient_internet("svn.python.org"):
1156 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1157 cert_reqs=ssl.CERT_REQUIRED,
1158 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1159 try:
1160 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
1161 self.assertTrue(s.getpeercert())
1162 finally:
1163 s.close()
1164
1165 def test_non_blocking_connect_ex(self):
1166 # Issue #11326: non-blocking connect_ex() should allow handshake
1167 # to proceed after the socket gets ready.
1168 with support.transient_internet("svn.python.org"):
1169 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1170 cert_reqs=ssl.CERT_REQUIRED,
1171 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
1172 do_handshake_on_connect=False)
1173 try:
1174 s.setblocking(False)
1175 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8a14a0c2011-02-27 15:44:12 +00001176 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1177 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001178 # Wait for connect to finish
1179 select.select([], [s], [], 5.0)
1180 # Non-blocking handshake
1181 while True:
1182 try:
1183 s.do_handshake()
1184 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001185 except ssl.SSLWantReadError:
1186 select.select([s], [], [], 5.0)
1187 except ssl.SSLWantWriteError:
1188 select.select([], [s], [], 5.0)
Antoine Pitroue93bf7a2011-02-26 23:24:06 +00001189 # SSL established
1190 self.assertTrue(s.getpeercert())
1191 finally:
1192 s.close()
1193
Antoine Pitroub4410db2011-05-18 18:51:06 +02001194 def test_timeout_connect_ex(self):
1195 # Issue #12065: on a timeout, connect_ex() should return the original
1196 # errno (mimicking the behaviour of non-SSL sockets).
1197 with support.transient_internet("svn.python.org"):
1198 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1199 cert_reqs=ssl.CERT_REQUIRED,
1200 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
1201 do_handshake_on_connect=False)
1202 try:
1203 s.settimeout(0.0000001)
1204 rc = s.connect_ex(('svn.python.org', 443))
1205 if rc == 0:
1206 self.skipTest("svn.python.org responded too quickly")
1207 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1208 finally:
1209 s.close()
1210
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001211 def test_connect_ex_error(self):
Antoine Pitrouddb87ab2012-12-28 19:07:43 +01001212 with support.transient_internet("svn.python.org"):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001213 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1214 cert_reqs=ssl.CERT_REQUIRED,
1215 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1216 try:
Christian Heimesde570742013-12-16 21:15:44 +01001217 rc = s.connect_ex(("svn.python.org", 444))
1218 # Issue #19919: Windows machines or VMs hosted on Windows
1219 # machines sometimes return EWOULDBLOCK.
1220 self.assertIn(rc, (errno.ECONNREFUSED, errno.EWOULDBLOCK))
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001221 finally:
1222 s.close()
1223
Antoine Pitrou152efa22010-05-16 18:19:27 +00001224 def test_connect_with_context(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001225 with support.transient_internet("svn.python.org"):
1226 # Same as test_connect, but with a separately created context
1227 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1228 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1229 s.connect(("svn.python.org", 443))
1230 try:
1231 self.assertEqual({}, s.getpeercert())
1232 finally:
1233 s.close()
Antoine Pitroud5323212010-10-22 18:19:07 +00001234 # Same with a server hostname
1235 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1236 server_hostname="svn.python.org")
1237 if ssl.HAS_SNI:
1238 s.connect(("svn.python.org", 443))
1239 s.close()
1240 else:
1241 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001242 # This should fail because we have no verification certs
1243 ctx.verify_mode = ssl.CERT_REQUIRED
1244 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Ezio Melottied3a7d22010-12-01 02:32:32 +00001245 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
Antoine Pitrou350c7222010-09-09 13:31:46 +00001246 s.connect, ("svn.python.org", 443))
Antoine Pitrou152efa22010-05-16 18:19:27 +00001247 s.close()
Antoine Pitrou350c7222010-09-09 13:31:46 +00001248 # This should succeed because we specify the root cert
1249 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
1250 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1251 s.connect(("svn.python.org", 443))
1252 try:
1253 cert = s.getpeercert()
1254 self.assertTrue(cert)
1255 finally:
1256 s.close()
Antoine Pitrou152efa22010-05-16 18:19:27 +00001257
1258 def test_connect_capath(self):
1259 # Verify server certificates using the `capath` argument
Antoine Pitrou467f28d2010-05-16 19:22:44 +00001260 # NOTE: the subject hashing algorithm has been changed between
1261 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1262 # contain both versions of each certificate (same content, different
Antoine Pitroud7e4c1c2010-05-17 14:13:10 +00001263 # filename) for this test to be portable across OpenSSL releases.
Antoine Pitrou350c7222010-09-09 13:31:46 +00001264 with support.transient_internet("svn.python.org"):
1265 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1266 ctx.verify_mode = ssl.CERT_REQUIRED
1267 ctx.load_verify_locations(capath=CAPATH)
1268 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1269 s.connect(("svn.python.org", 443))
1270 try:
1271 cert = s.getpeercert()
1272 self.assertTrue(cert)
1273 finally:
1274 s.close()
1275 # Same with a bytes `capath` argument
1276 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1277 ctx.verify_mode = ssl.CERT_REQUIRED
1278 ctx.load_verify_locations(capath=BYTES_CAPATH)
1279 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1280 s.connect(("svn.python.org", 443))
1281 try:
1282 cert = s.getpeercert()
1283 self.assertTrue(cert)
1284 finally:
1285 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001286
Christian Heimesefff7062013-11-21 03:35:02 +01001287 def test_connect_cadata(self):
1288 with open(CAFILE_CACERT) as f:
1289 pem = f.read()
1290 der = ssl.PEM_cert_to_DER_cert(pem)
1291 with support.transient_internet("svn.python.org"):
1292 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1293 ctx.verify_mode = ssl.CERT_REQUIRED
1294 ctx.load_verify_locations(cadata=pem)
1295 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1296 s.connect(("svn.python.org", 443))
1297 cert = s.getpeercert()
1298 self.assertTrue(cert)
1299
1300 # same with DER
1301 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1302 ctx.verify_mode = ssl.CERT_REQUIRED
1303 ctx.load_verify_locations(cadata=der)
1304 with ctx.wrap_socket(socket.socket(socket.AF_INET)) as s:
1305 s.connect(("svn.python.org", 443))
1306 cert = s.getpeercert()
1307 self.assertTrue(cert)
1308
Antoine Pitroue3220242010-04-24 11:13:53 +00001309 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1310 def test_makefile_close(self):
1311 # Issue #5238: creating a file-like object with makefile() shouldn't
1312 # delay closing the underlying "real socket" (here tested with its
1313 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou350c7222010-09-09 13:31:46 +00001314 with support.transient_internet("svn.python.org"):
1315 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
1316 ss.connect(("svn.python.org", 443))
1317 fd = ss.fileno()
1318 f = ss.makefile()
1319 f.close()
1320 # The fd is still open
Antoine Pitroue3220242010-04-24 11:13:53 +00001321 os.read(fd, 0)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001322 # Closing the SSL socket should close the fd too
1323 ss.close()
1324 gc.collect()
1325 with self.assertRaises(OSError) as e:
1326 os.read(fd, 0)
1327 self.assertEqual(e.exception.errno, errno.EBADF)
Antoine Pitroue3220242010-04-24 11:13:53 +00001328
Antoine Pitrou480a1242010-04-28 21:37:09 +00001329 def test_non_blocking_handshake(self):
Antoine Pitrou350c7222010-09-09 13:31:46 +00001330 with support.transient_internet("svn.python.org"):
1331 s = socket.socket(socket.AF_INET)
1332 s.connect(("svn.python.org", 443))
1333 s.setblocking(False)
1334 s = ssl.wrap_socket(s,
1335 cert_reqs=ssl.CERT_NONE,
1336 do_handshake_on_connect=False)
1337 count = 0
1338 while True:
1339 try:
1340 count += 1
1341 s.do_handshake()
1342 break
Antoine Pitrou41032a62011-10-27 23:56:55 +02001343 except ssl.SSLWantReadError:
1344 select.select([s], [], [])
1345 except ssl.SSLWantWriteError:
1346 select.select([], [s], [])
Antoine Pitrou350c7222010-09-09 13:31:46 +00001347 s.close()
1348 if support.verbose:
1349 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001350
Antoine Pitrou480a1242010-04-28 21:37:09 +00001351 def test_get_server_certificate(self):
Antoine Pitrou15399c32011-04-28 19:23:55 +02001352 def _test_get_server_certificate(host, port, cert=None):
1353 with support.transient_internet(host):
Benjamin Petersond0fc83d2014-03-12 18:10:47 -05001354 pem = ssl.get_server_certificate((host, port),
1355 ssl.PROTOCOL_SSLv23)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001356 if not pem:
1357 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001358
Antoine Pitrou15399c32011-04-28 19:23:55 +02001359 try:
Benjamin Petersond0fc83d2014-03-12 18:10:47 -05001360 pem = ssl.get_server_certificate((host, port),
1361 ssl.PROTOCOL_SSLv23,
1362 ca_certs=CERTFILE)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001363 except ssl.SSLError as x:
1364 #should fail
1365 if support.verbose:
1366 sys.stdout.write("%s\n" % x)
1367 else:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001368 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
1369
Benjamin Petersond0fc83d2014-03-12 18:10:47 -05001370 pem = ssl.get_server_certificate((host, port),
Benjamin Petersoncf25c5c2014-03-12 18:05:53 -05001371 ssl.PROTOCOL_SSLv23,
Benjamin Petersond0fc83d2014-03-12 18:10:47 -05001372 ca_certs=cert)
Antoine Pitrou15399c32011-04-28 19:23:55 +02001373 if not pem:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001374 self.fail("No server certificate on %s:%s!" % (host, port))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001375 if support.verbose:
Antoine Pitrou5aefa662011-04-28 19:24:46 +02001376 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
Antoine Pitrou350c7222010-09-09 13:31:46 +00001377
Antoine Pitrou15399c32011-04-28 19:23:55 +02001378 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
1379 if support.IPV6_ENABLED:
1380 _test_get_server_certificate('ipv6.google.com', 443)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001381
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001382 def test_ciphers(self):
1383 remote = ("svn.python.org", 443)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001384 with support.transient_internet(remote[0]):
Antoine Pitroue1ceb502013-01-12 21:54:44 +01001385 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1386 cert_reqs=ssl.CERT_NONE, ciphers="ALL") as s:
1387 s.connect(remote)
1388 with ssl.wrap_socket(socket.socket(socket.AF_INET),
1389 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") as s:
1390 s.connect(remote)
Antoine Pitrou350c7222010-09-09 13:31:46 +00001391 # Error checking can happen at instantiation or when connecting
Ezio Melottied3a7d22010-12-01 02:32:32 +00001392 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
Antoine Pitroud2eca372010-10-29 23:41:37 +00001393 with socket.socket(socket.AF_INET) as sock:
1394 s = ssl.wrap_socket(sock,
1395 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1396 s.connect(remote)
Antoine Pitrouf4c7bad2010-08-15 23:02:22 +00001397
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001398 def test_algorithms(self):
1399 # Issue #8484: all algorithms should be available when verifying a
1400 # certificate.
Antoine Pitrou29619b22010-04-22 18:43:31 +00001401 # SHA256 was added in OpenSSL 0.9.8
1402 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1403 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001404 # sha256.tbs-internet.com needs SNI to use the correct certificate
1405 if not ssl.HAS_SNI:
1406 self.skipTest("SNI needed for this test")
Victor Stinnerf332abb2011-01-08 03:16:05 +00001407 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
1408 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001409 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitrou160fd932011-01-08 10:23:29 +00001410 with support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrou16f6f832012-05-04 16:26:02 +02001411 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1412 ctx.verify_mode = ssl.CERT_REQUIRED
1413 ctx.load_verify_locations(sha256_cert)
1414 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1415 server_hostname="sha256.tbs-internet.com")
Antoine Pitroufec12ff2010-04-21 19:46:23 +00001416 try:
1417 s.connect(remote)
1418 if support.verbose:
1419 sys.stdout.write("\nCipher with %r is %r\n" %
1420 (remote, s.cipher()))
1421 sys.stdout.write("Certificate is:\n%s\n" %
1422 pprint.pformat(s.getpeercert()))
1423 finally:
1424 s.close()
1425
Christian Heimes9a5395a2013-06-17 15:44:12 +02001426 def test_get_ca_certs_capath(self):
1427 # capath certs are loaded on request
1428 with support.transient_internet("svn.python.org"):
1429 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1430 ctx.verify_mode = ssl.CERT_REQUIRED
1431 ctx.load_verify_locations(capath=CAPATH)
1432 self.assertEqual(ctx.get_ca_certs(), [])
1433 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1434 s.connect(("svn.python.org", 443))
1435 try:
1436 cert = s.getpeercert()
1437 self.assertTrue(cert)
1438 finally:
1439 s.close()
1440 self.assertEqual(len(ctx.get_ca_certs()), 1)
1441
Christian Heimes575596e2013-12-15 21:49:17 +01001442 @needs_sni
Christian Heimes8e7f3942013-12-05 07:41:08 +01001443 def test_context_setget(self):
1444 # Check that the context of a connected socket can be replaced.
1445 with support.transient_internet("svn.python.org"):
1446 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1447 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1448 s = socket.socket(socket.AF_INET)
1449 with ctx1.wrap_socket(s) as ss:
1450 ss.connect(("svn.python.org", 443))
1451 self.assertIs(ss.context, ctx1)
1452 self.assertIs(ss._sslobj.context, ctx1)
1453 ss.context = ctx2
1454 self.assertIs(ss.context, ctx2)
1455 self.assertIs(ss._sslobj.context, ctx2)
1456
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001457try:
1458 import threading
1459except ImportError:
1460 _have_threads = False
1461else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001462 _have_threads = True
1463
Antoine Pitrou803e6d62010-10-13 10:36:15 +00001464 from test.ssl_servers import make_https_server
1465
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001466 class ThreadedEchoServer(threading.Thread):
1467
1468 class ConnectionHandler(threading.Thread):
1469
1470 """A mildly complicated class, because we want it to work both
1471 with and without the SSL wrapper around the socket connection, so
1472 that we can test the STARTTLS functionality."""
1473
Bill Janssen6e027db2007-11-15 22:23:56 +00001474 def __init__(self, server, connsock, addr):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001475 self.server = server
1476 self.running = False
1477 self.sock = connsock
Bill Janssen6e027db2007-11-15 22:23:56 +00001478 self.addr = addr
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001479 self.sock.setblocking(1)
1480 self.sslconn = None
1481 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001482 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001483
Antoine Pitrou480a1242010-04-28 21:37:09 +00001484 def wrap_conn(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001485 try:
Antoine Pitroub5218772010-05-21 09:56:06 +00001486 self.sslconn = self.server.context.wrap_socket(
1487 self.sock, server_side=True)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001488 self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
Nadeem Vawdaad246bf2013-03-03 22:44:22 +01001489 except (ssl.SSLError, ConnectionResetError) as e:
1490 # We treat ConnectionResetError as though it were an
1491 # SSLError - OpenSSL on Ubuntu abruptly closes the
1492 # connection when asked to use an unsupported protocol.
1493 #
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001494 # XXX Various errors can have happened here, for example
1495 # a mismatching protocol version, an invalid certificate,
1496 # or a low-level bug. This should be made more discriminating.
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001497 self.server.conn_errors.append(e)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001498 if self.server.chatty:
Bill Janssen6e027db2007-11-15 22:23:56 +00001499 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001500 self.running = False
1501 self.server.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001502 self.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001503 return False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001504 else:
Antoine Pitroub5218772010-05-21 09:56:06 +00001505 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001506 cert = self.sslconn.getpeercert()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001507 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001508 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1509 cert_binary = self.sslconn.getpeercert(True)
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001510 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001511 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1512 cipher = self.sslconn.cipher()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001513 if support.verbose and self.server.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001514 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001515 sys.stdout.write(" server: selected protocol is now "
1516 + str(self.sslconn.selected_npn_protocol()) + "\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001517 return True
1518
1519 def read(self):
1520 if self.sslconn:
1521 return self.sslconn.read()
1522 else:
1523 return self.sock.recv(1024)
1524
1525 def write(self, bytes):
1526 if self.sslconn:
1527 return self.sslconn.write(bytes)
1528 else:
1529 return self.sock.send(bytes)
1530
1531 def close(self):
1532 if self.sslconn:
1533 self.sslconn.close()
1534 else:
1535 self.sock.close()
1536
Antoine Pitrou480a1242010-04-28 21:37:09 +00001537 def run(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001538 self.running = True
1539 if not self.server.starttls_server:
1540 if not self.wrap_conn():
1541 return
1542 while self.running:
1543 try:
1544 msg = self.read()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001545 stripped = msg.strip()
1546 if not stripped:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001547 # eof, so quit this handler
1548 self.running = False
1549 self.close()
Antoine Pitrou480a1242010-04-28 21:37:09 +00001550 elif stripped == b'over':
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001551 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001552 sys.stdout.write(" server: client closed connection\n")
1553 self.close()
1554 return
Bill Janssen6e027db2007-11-15 22:23:56 +00001555 elif (self.server.starttls_server and
Antoine Pitrou764b8782010-04-28 22:57:15 +00001556 stripped == b'STARTTLS'):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001557 if support.verbose and self.server.connectionchatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001558 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001559 self.write(b"OK\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001560 if not self.wrap_conn():
1561 return
Bill Janssen40a0f662008-08-12 16:56:25 +00001562 elif (self.server.starttls_server and self.sslconn
Antoine Pitrou764b8782010-04-28 22:57:15 +00001563 and stripped == b'ENDTLS'):
Bill Janssen40a0f662008-08-12 16:56:25 +00001564 if support.verbose and self.server.connectionchatty:
1565 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00001566 self.write(b"OK\n")
Bill Janssen40a0f662008-08-12 16:56:25 +00001567 self.sock = self.sslconn.unwrap()
1568 self.sslconn = None
1569 if support.verbose and self.server.connectionchatty:
1570 sys.stdout.write(" server: connection is now unencrypted...\n")
Antoine Pitroud6494802011-07-21 01:11:30 +02001571 elif stripped == b'CB tls-unique':
1572 if support.verbose and self.server.connectionchatty:
1573 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1574 data = self.sslconn.get_channel_binding("tls-unique")
1575 self.write(repr(data).encode("us-ascii") + b"\n")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001576 else:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001577 if (support.verbose and
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001578 self.server.connectionchatty):
1579 ctype = (self.sslconn and "encrypted") or "unencrypted"
Antoine Pitrou480a1242010-04-28 21:37:09 +00001580 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1581 % (msg, ctype, msg.lower(), ctype))
1582 self.write(msg.lower())
Andrew Svetlov0832af62012-12-18 23:10:48 +02001583 except OSError:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001584 if self.server.chatty:
1585 handle_error("Test server failure:\n")
1586 self.close()
1587 self.running = False
1588 # normally, we'd just stop here, but for the test
1589 # harness, we want to stop the server
1590 self.server.stop()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001591
Antoine Pitroub5218772010-05-21 09:56:06 +00001592 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001593 certreqs=None, cacerts=None,
Antoine Pitrou2d9cb9c2010-04-17 17:40:45 +00001594 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001595 npn_protocols=None, ciphers=None, context=None):
Antoine Pitroub5218772010-05-21 09:56:06 +00001596 if context:
1597 self.context = context
1598 else:
1599 self.context = ssl.SSLContext(ssl_version
1600 if ssl_version is not None
1601 else ssl.PROTOCOL_TLSv1)
1602 self.context.verify_mode = (certreqs if certreqs is not None
1603 else ssl.CERT_NONE)
1604 if cacerts:
1605 self.context.load_verify_locations(cacerts)
1606 if certificate:
1607 self.context.load_cert_chain(certificate)
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001608 if npn_protocols:
1609 self.context.set_npn_protocols(npn_protocols)
Antoine Pitroub5218772010-05-21 09:56:06 +00001610 if ciphers:
1611 self.context.set_ciphers(ciphers)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001612 self.chatty = chatty
1613 self.connectionchatty = connectionchatty
1614 self.starttls_server = starttls_server
1615 self.sock = socket.socket()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001616 self.port = support.bind_port(self.sock)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001617 self.flag = None
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001618 self.active = False
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001619 self.selected_protocols = []
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001620 self.conn_errors = []
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001621 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001622 self.daemon = True
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001623
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001624 def __enter__(self):
1625 self.start(threading.Event())
1626 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001627 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001628
1629 def __exit__(self, *args):
1630 self.stop()
1631 self.join()
1632
Antoine Pitrou480a1242010-04-28 21:37:09 +00001633 def start(self, flag=None):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001634 self.flag = flag
1635 threading.Thread.start(self)
1636
Antoine Pitrou480a1242010-04-28 21:37:09 +00001637 def run(self):
Antoine Pitrouaf7c6022010-04-27 09:56:02 +00001638 self.sock.settimeout(0.05)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001639 self.sock.listen(5)
1640 self.active = True
1641 if self.flag:
1642 # signal an event
1643 self.flag.set()
1644 while self.active:
1645 try:
1646 newconn, connaddr = self.sock.accept()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001647 if support.verbose and self.chatty:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001648 sys.stdout.write(' server: new connection from '
Bill Janssen6e027db2007-11-15 22:23:56 +00001649 + repr(connaddr) + '\n')
1650 handler = self.ConnectionHandler(self, newconn, connaddr)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001651 handler.start()
Antoine Pitroueced82e2012-01-27 17:33:01 +01001652 handler.join()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001653 except socket.timeout:
1654 pass
1655 except KeyboardInterrupt:
1656 self.stop()
Bill Janssen6e027db2007-11-15 22:23:56 +00001657 self.sock.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001658
Antoine Pitrou480a1242010-04-28 21:37:09 +00001659 def stop(self):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001660 self.active = False
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001661
Bill Janssen54cc54c2007-12-14 22:08:56 +00001662 class AsyncoreEchoServer(threading.Thread):
1663
1664 # this one's based on asyncore.dispatcher
1665
1666 class EchoServer (asyncore.dispatcher):
1667
1668 class ConnectionHandler (asyncore.dispatcher_with_send):
1669
1670 def __init__(self, conn, certfile):
1671 self.socket = ssl.wrap_socket(conn, server_side=True,
1672 certfile=certfile,
1673 do_handshake_on_connect=False)
1674 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001675 self._ssl_accepting = True
1676 self._do_ssl_handshake()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001677
1678 def readable(self):
1679 if isinstance(self.socket, ssl.SSLSocket):
1680 while self.socket.pending() > 0:
1681 self.handle_read_event()
1682 return True
1683
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001684 def _do_ssl_handshake(self):
1685 try:
1686 self.socket.do_handshake()
Antoine Pitrou41032a62011-10-27 23:56:55 +02001687 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1688 return
1689 except ssl.SSLEOFError:
1690 return self.handle_close()
1691 except ssl.SSLError:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001692 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02001693 except OSError as err:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001694 if err.args[0] == errno.ECONNABORTED:
1695 return self.handle_close()
Bill Janssen54cc54c2007-12-14 22:08:56 +00001696 else:
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00001697 self._ssl_accepting = False
1698
1699 def handle_read(self):
1700 if self._ssl_accepting:
1701 self._do_ssl_handshake()
1702 else:
1703 data = self.recv(1024)
1704 if support.verbose:
1705 sys.stdout.write(" server: read %s from client\n" % repr(data))
1706 if not data:
1707 self.close()
1708 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001709 self.send(data.lower())
Bill Janssen54cc54c2007-12-14 22:08:56 +00001710
1711 def handle_close(self):
Bill Janssen2f5799b2008-06-29 00:08:12 +00001712 self.close()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001713 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001714 sys.stdout.write(" server: closed connection %s\n" % self.socket)
1715
1716 def handle_error(self):
1717 raise
1718
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001719 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001720 self.certfile = certfile
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001721 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1722 self.port = support.bind_port(sock, '')
1723 asyncore.dispatcher.__init__(self, sock)
Bill Janssen54cc54c2007-12-14 22:08:56 +00001724 self.listen(5)
1725
Giampaolo Rodolà977c7072010-10-04 21:08:36 +00001726 def handle_accepted(self, sock_obj, addr):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001727 if support.verbose:
Bill Janssen54cc54c2007-12-14 22:08:56 +00001728 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
1729 self.ConnectionHandler(sock_obj, self.certfile)
1730
1731 def handle_error(self):
1732 raise
1733
Trent Nelson78520002008-04-10 20:54:35 +00001734 def __init__(self, certfile):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001735 self.flag = None
1736 self.active = False
Antoine Pitrou773b5db2010-04-27 08:53:36 +00001737 self.server = self.EchoServer(certfile)
1738 self.port = self.server.port
Bill Janssen54cc54c2007-12-14 22:08:56 +00001739 threading.Thread.__init__(self)
Benjamin Peterson4171da52008-08-18 21:11:09 +00001740 self.daemon = True
Bill Janssen54cc54c2007-12-14 22:08:56 +00001741
1742 def __str__(self):
1743 return "<%s %s>" % (self.__class__.__name__, self.server)
1744
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001745 def __enter__(self):
1746 self.start(threading.Event())
1747 self.flag.wait()
Antoine Pitrou8f85f902012-01-03 22:46:48 +01001748 return self
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001749
1750 def __exit__(self, *args):
1751 if support.verbose:
1752 sys.stdout.write(" cleanup: stopping server.\n")
1753 self.stop()
1754 if support.verbose:
1755 sys.stdout.write(" cleanup: joining server thread.\n")
1756 self.join()
1757 if support.verbose:
1758 sys.stdout.write(" cleanup: successfully joined.\n")
1759
Bill Janssen54cc54c2007-12-14 22:08:56 +00001760 def start (self, flag=None):
1761 self.flag = flag
1762 threading.Thread.start(self)
1763
Antoine Pitrou480a1242010-04-28 21:37:09 +00001764 def run(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001765 self.active = True
1766 if self.flag:
1767 self.flag.set()
1768 while self.active:
1769 try:
1770 asyncore.loop(1)
1771 except:
1772 pass
1773
Antoine Pitrou480a1242010-04-28 21:37:09 +00001774 def stop(self):
Bill Janssen54cc54c2007-12-14 22:08:56 +00001775 self.active = False
1776 self.server.close()
1777
Antoine Pitrou480a1242010-04-28 21:37:09 +00001778 def bad_cert_test(certfile):
1779 """
1780 Launch a server with CERT_REQUIRED, and check that trying to
1781 connect to it with the given client certificate fails.
1782 """
Trent Nelson78520002008-04-10 20:54:35 +00001783 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001784 certreqs=ssl.CERT_REQUIRED,
Bill Janssen6e027db2007-11-15 22:23:56 +00001785 cacerts=CERTFILE, chatty=False,
1786 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001787 with server:
Thomas Woutersed03b412007-08-28 21:37:11 +00001788 try:
Antoine Pitroud2eca372010-10-29 23:41:37 +00001789 with socket.socket() as sock:
1790 s = ssl.wrap_socket(sock,
1791 certfile=certfile,
1792 ssl_version=ssl.PROTOCOL_TLSv1)
1793 s.connect((HOST, server.port))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001794 except ssl.SSLError as x:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001795 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001796 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
Andrew Svetlov0832af62012-12-18 23:10:48 +02001797 except OSError as x:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001798 if support.verbose:
Andrew Svetlov0832af62012-12-18 23:10:48 +02001799 sys.stdout.write("\nOSError is %s\n" % x.args[1])
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001800 except OSError as x:
Giampaolo Rodolàcd9dfb92010-08-29 20:56:56 +00001801 if x.errno != errno.ENOENT:
1802 raise
Giampaolo Rodolà745ab382010-08-29 19:25:49 +00001803 if support.verbose:
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02001804 sys.stdout.write("\OSError is %s\n" % str(x))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001805 else:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001806 raise AssertionError("Use of invalid cert should have failed!")
Thomas Woutersed03b412007-08-28 21:37:11 +00001807
Antoine Pitroub5218772010-05-21 09:56:06 +00001808 def server_params_test(client_context, server_context, indata=b"FOO\n",
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001809 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou480a1242010-04-28 21:37:09 +00001810 """
1811 Launch a server, connect a client to it and try various reads
1812 and writes.
1813 """
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001814 stats = {}
Antoine Pitroub5218772010-05-21 09:56:06 +00001815 server = ThreadedEchoServer(context=server_context,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001816 chatty=chatty,
Bill Janssen6e027db2007-11-15 22:23:56 +00001817 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001818 with server:
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001819 with client_context.wrap_socket(socket.socket(),
1820 server_hostname=sni_name) as s:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001821 s.connect((HOST, server.port))
1822 for arg in [indata, bytearray(indata), memoryview(indata)]:
1823 if connectionchatty:
1824 if support.verbose:
1825 sys.stdout.write(
1826 " client: sending %r...\n" % indata)
1827 s.write(arg)
1828 outdata = s.read()
1829 if connectionchatty:
1830 if support.verbose:
1831 sys.stdout.write(" client: read %r\n" % outdata)
1832 if outdata != indata.lower():
1833 raise AssertionError(
1834 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1835 % (outdata[:20], len(outdata),
1836 indata[:20].lower(), len(indata)))
1837 s.write(b"over\n")
Antoine Pitrou7d7aede2009-11-25 18:55:32 +00001838 if connectionchatty:
1839 if support.verbose:
Antoine Pitroueba63c42012-01-28 17:38:34 +01001840 sys.stdout.write(" client: closing connection.\n")
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001841 stats.update({
Antoine Pitrouce816a52012-01-28 17:40:23 +01001842 'compression': s.compression(),
1843 'cipher': s.cipher(),
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01001844 'peercert': s.getpeercert(),
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001845 'client_npn_protocol': s.selected_npn_protocol()
1846 })
Antoine Pitroueba63c42012-01-28 17:38:34 +01001847 s.close()
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01001848 stats['server_npn_protocols'] = server.selected_protocols
1849 return stats
Thomas Woutersed03b412007-08-28 21:37:11 +00001850
Antoine Pitroub5218772010-05-21 09:56:06 +00001851 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1852 certsreqs=None, server_options=0, client_options=0):
Benjamin Peterson2a691a82008-03-31 01:51:45 +00001853 if certsreqs is None:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001854 certsreqs = ssl.CERT_NONE
Antoine Pitrou480a1242010-04-28 21:37:09 +00001855 certtype = {
1856 ssl.CERT_NONE: "CERT_NONE",
1857 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1858 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1859 }[certsreqs]
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001860 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001861 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001862 sys.stdout.write(formatstr %
1863 (ssl.get_protocol_name(client_protocol),
1864 ssl.get_protocol_name(server_protocol),
1865 certtype))
Antoine Pitroub5218772010-05-21 09:56:06 +00001866 client_context = ssl.SSLContext(client_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01001867 client_context.options |= client_options
Antoine Pitroub5218772010-05-21 09:56:06 +00001868 server_context = ssl.SSLContext(server_protocol)
Antoine Pitrou32c49152014-01-09 21:28:48 +01001869 server_context.options |= server_options
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01001870
1871 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
1872 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
1873 # starting from OpenSSL 1.0.0 (see issue #8322).
1874 if client_context.protocol == ssl.PROTOCOL_SSLv23:
1875 client_context.set_ciphers("ALL")
1876
Antoine Pitroub5218772010-05-21 09:56:06 +00001877 for ctx in (client_context, server_context):
1878 ctx.verify_mode = certsreqs
Antoine Pitroub5218772010-05-21 09:56:06 +00001879 ctx.load_cert_chain(CERTFILE)
1880 ctx.load_verify_locations(CERTFILE)
1881 try:
1882 server_params_test(client_context, server_context,
1883 chatty=False, connectionchatty=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001884 # Protocol mismatch can result in either an SSLError, or a
1885 # "Connection reset by peer" error.
1886 except ssl.SSLError:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001887 if expect_success:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001888 raise
Andrew Svetlov0832af62012-12-18 23:10:48 +02001889 except OSError as e:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001890 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001891 raise
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001892 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00001893 if not expect_success:
Antoine Pitroud75b2a92010-05-06 14:15:10 +00001894 raise AssertionError(
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001895 "Client protocol %s succeeded with server protocol %s!"
1896 % (ssl.get_protocol_name(client_protocol),
1897 ssl.get_protocol_name(server_protocol)))
1898
1899
Bill Janssen6e027db2007-11-15 22:23:56 +00001900 class ThreadedTests(unittest.TestCase):
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001901
Antoine Pitrou23df4832010-08-04 17:14:06 +00001902 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00001903 def test_echo(self):
1904 """Basic test of an SSL client connecting to a server"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001905 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001906 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001907 for protocol in PROTOCOLS:
Antoine Pitrou972d5bb2013-03-29 17:56:03 +01001908 with self.subTest(protocol=ssl._PROTOCOL_NAMES[protocol]):
1909 context = ssl.SSLContext(protocol)
1910 context.load_cert_chain(CERTFILE)
1911 server_params_test(context, context,
1912 chatty=True, connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001913
Antoine Pitrou480a1242010-04-28 21:37:09 +00001914 def test_getpeercert(self):
Benjamin Petersonee8712c2008-05-20 21:35:26 +00001915 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001916 sys.stdout.write("\n")
Antoine Pitroub5218772010-05-21 09:56:06 +00001917 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1918 context.verify_mode = ssl.CERT_REQUIRED
1919 context.load_verify_locations(CERTFILE)
1920 context.load_cert_chain(CERTFILE)
1921 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01001922 with server:
Antoine Pitrou20b85552013-09-29 19:50:53 +02001923 s = context.wrap_socket(socket.socket(),
1924 do_handshake_on_connect=False)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001925 s.connect((HOST, server.port))
Antoine Pitrou20b85552013-09-29 19:50:53 +02001926 # getpeercert() raise ValueError while the handshake isn't
1927 # done.
1928 with self.assertRaises(ValueError):
1929 s.getpeercert()
1930 s.do_handshake()
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001931 cert = s.getpeercert()
1932 self.assertTrue(cert, "Can't get peer certificate.")
1933 cipher = s.cipher()
1934 if support.verbose:
1935 sys.stdout.write(pprint.pformat(cert) + '\n')
1936 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1937 if 'subject' not in cert:
1938 self.fail("No subject field in certificate: %s." %
1939 pprint.pformat(cert))
1940 if ((('organizationName', 'Python Software Foundation'),)
1941 not in cert['subject']):
1942 self.fail(
1943 "Missing or invalid 'organizationName' field in certificate subject; "
1944 "should be 'Python Software Foundation'.")
Antoine Pitroufb046912010-11-09 20:21:19 +00001945 self.assertIn('notBefore', cert)
1946 self.assertIn('notAfter', cert)
1947 before = ssl.cert_time_to_seconds(cert['notBefore'])
1948 after = ssl.cert_time_to_seconds(cert['notAfter'])
1949 self.assertLess(before, after)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00001950 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00001951
Christian Heimes2427b502013-11-23 11:24:32 +01001952 @unittest.skipUnless(have_verify_flags(),
1953 "verify_flags need OpenSSL > 0.9.8")
Christian Heimes22587792013-11-21 23:56:13 +01001954 def test_crl_check(self):
1955 if support.verbose:
1956 sys.stdout.write("\n")
1957
1958 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1959 server_context.load_cert_chain(SIGNED_CERTFILE)
1960
1961 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1962 context.verify_mode = ssl.CERT_REQUIRED
1963 context.load_verify_locations(SIGNING_CA)
Christian Heimes32f0c7a2013-11-22 03:43:48 +01001964 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT)
Christian Heimes22587792013-11-21 23:56:13 +01001965
1966 # VERIFY_DEFAULT should pass
1967 server = ThreadedEchoServer(context=server_context, chatty=True)
1968 with server:
1969 with context.wrap_socket(socket.socket()) as s:
1970 s.connect((HOST, server.port))
1971 cert = s.getpeercert()
1972 self.assertTrue(cert, "Can't get peer certificate.")
1973
1974 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
Christian Heimes32f0c7a2013-11-22 03:43:48 +01001975 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
Christian Heimes22587792013-11-21 23:56:13 +01001976
1977 server = ThreadedEchoServer(context=server_context, chatty=True)
1978 with server:
1979 with context.wrap_socket(socket.socket()) as s:
1980 with self.assertRaisesRegex(ssl.SSLError,
1981 "certificate verify failed"):
1982 s.connect((HOST, server.port))
1983
1984 # now load a CRL file. The CRL file is signed by the CA.
1985 context.load_verify_locations(CRLFILE)
1986
1987 server = ThreadedEchoServer(context=server_context, chatty=True)
1988 with server:
1989 with context.wrap_socket(socket.socket()) as s:
1990 s.connect((HOST, server.port))
1991 cert = s.getpeercert()
1992 self.assertTrue(cert, "Can't get peer certificate.")
1993
Christian Heimes575596e2013-12-15 21:49:17 +01001994 @needs_sni
Christian Heimes1aa9a752013-12-02 02:41:19 +01001995 def test_check_hostname(self):
1996 if support.verbose:
1997 sys.stdout.write("\n")
1998
1999 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2000 server_context.load_cert_chain(SIGNED_CERTFILE)
2001
2002 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2003 context.verify_mode = ssl.CERT_REQUIRED
2004 context.check_hostname = True
2005 context.load_verify_locations(SIGNING_CA)
2006
2007 # correct hostname should verify
2008 server = ThreadedEchoServer(context=server_context, chatty=True)
2009 with server:
2010 with context.wrap_socket(socket.socket(),
2011 server_hostname="localhost") as s:
2012 s.connect((HOST, server.port))
2013 cert = s.getpeercert()
2014 self.assertTrue(cert, "Can't get peer certificate.")
2015
2016 # incorrect hostname should raise an exception
2017 server = ThreadedEchoServer(context=server_context, chatty=True)
2018 with server:
2019 with context.wrap_socket(socket.socket(),
2020 server_hostname="invalid") as s:
2021 with self.assertRaisesRegex(ssl.CertificateError,
2022 "hostname 'invalid' doesn't match 'localhost'"):
2023 s.connect((HOST, server.port))
2024
2025 # missing server_hostname arg should cause an exception, too
2026 server = ThreadedEchoServer(context=server_context, chatty=True)
2027 with server:
2028 with socket.socket() as s:
2029 with self.assertRaisesRegex(ValueError,
2030 "check_hostname requires server_hostname"):
2031 context.wrap_socket(s)
2032
Antoine Pitrou480a1242010-04-28 21:37:09 +00002033 def test_empty_cert(self):
2034 """Connecting with an empty cert file"""
2035 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2036 "nullcert.pem"))
2037 def test_malformed_cert(self):
2038 """Connecting with a badly formatted certificate (syntax error)"""
2039 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2040 "badcert.pem"))
2041 def test_nonexisting_cert(self):
2042 """Connecting with a non-existing cert file"""
2043 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2044 "wrongcert.pem"))
2045 def test_malformed_key(self):
2046 """Connecting with a badly formatted key (syntax error)"""
2047 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2048 "badkey.pem"))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002049
Antoine Pitrou480a1242010-04-28 21:37:09 +00002050 def test_rude_shutdown(self):
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002051 """A brutal shutdown of an SSL server should raise an OSError
Antoine Pitrou480a1242010-04-28 21:37:09 +00002052 in the client when attempting handshake.
2053 """
Trent Nelson6b240cd2008-04-10 20:12:06 +00002054 listener_ready = threading.Event()
2055 listener_gone = threading.Event()
Antoine Pitrou480a1242010-04-28 21:37:09 +00002056
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002057 s = socket.socket()
2058 port = support.bind_port(s, HOST)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002059
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002060 # `listener` runs in a thread. It sits in an accept() until
2061 # the main thread connects. Then it rudely closes the socket,
2062 # and sets Event `listener_gone` to let the main thread know
2063 # the socket is gone.
Trent Nelson6b240cd2008-04-10 20:12:06 +00002064 def listener():
Trent Nelson6b240cd2008-04-10 20:12:06 +00002065 s.listen(5)
2066 listener_ready.set()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002067 newsock, addr = s.accept()
2068 newsock.close()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002069 s.close()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002070 listener_gone.set()
2071
2072 def connector():
2073 listener_ready.wait()
Antoine Pitroud2eca372010-10-29 23:41:37 +00002074 with socket.socket() as c:
2075 c.connect((HOST, port))
2076 listener_gone.wait()
2077 try:
2078 ssl_sock = ssl.wrap_socket(c)
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02002079 except OSError:
Antoine Pitroud2eca372010-10-29 23:41:37 +00002080 pass
2081 else:
2082 self.fail('connecting to closed SSL socket should have failed')
Trent Nelson6b240cd2008-04-10 20:12:06 +00002083
2084 t = threading.Thread(target=listener)
2085 t.start()
Antoine Pitrou773b5db2010-04-27 08:53:36 +00002086 try:
2087 connector()
2088 finally:
2089 t.join()
Trent Nelson6b240cd2008-04-10 20:12:06 +00002090
Antoine Pitrou23df4832010-08-04 17:14:06 +00002091 @skip_if_broken_ubuntu_ssl
Victor Stinner3de49192011-05-09 00:42:58 +02002092 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2093 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002094 def test_protocol_sslv2(self):
2095 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002096 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002097 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002098 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2099 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2100 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002101 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002102 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
2103 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002104 # SSLv23 client with specific SSL options
2105 if no_sslv2_implies_sslv3_hello():
2106 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2107 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2108 client_options=ssl.OP_NO_SSLv2)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002109 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002110 client_options=ssl.OP_NO_SSLv3)
Antoine Pitroucd3d7ca2014-01-09 20:02:20 +01002111 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
Antoine Pitroub5218772010-05-21 09:56:06 +00002112 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002113
Antoine Pitrou23df4832010-08-04 17:14:06 +00002114 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002115 def test_protocol_sslv23(self):
2116 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002117 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002118 sys.stdout.write("\n")
Victor Stinner3de49192011-05-09 00:42:58 +02002119 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2120 try:
2121 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
Andrew Svetlov0832af62012-12-18 23:10:48 +02002122 except OSError as x:
Victor Stinner3de49192011-05-09 00:42:58 +02002123 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2124 if support.verbose:
2125 sys.stdout.write(
2126 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2127 % str(x))
Antoine Pitrou480a1242010-04-28 21:37:09 +00002128 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
2129 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
2130 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002131
Antoine Pitrou480a1242010-04-28 21:37:09 +00002132 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
2133 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
2134 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002135
Antoine Pitrou480a1242010-04-28 21:37:09 +00002136 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
2137 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
2138 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002139
Antoine Pitroub5218772010-05-21 09:56:06 +00002140 # Server with specific SSL options
2141 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
2142 server_options=ssl.OP_NO_SSLv3)
2143 # Will choose TLSv1
2144 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2145 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2146 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2147 server_options=ssl.OP_NO_TLSv1)
2148
2149
Antoine Pitrou23df4832010-08-04 17:14:06 +00002150 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002151 def test_protocol_sslv3(self):
2152 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002153 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002154 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002155 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
2156 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
2157 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002158 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2159 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002160 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2161 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002162 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Antoine Pitroub5218772010-05-21 09:56:06 +00002163 if no_sslv2_implies_sslv3_hello():
2164 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2165 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
2166 client_options=ssl.OP_NO_SSLv2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002167
Antoine Pitrou23df4832010-08-04 17:14:06 +00002168 @skip_if_broken_ubuntu_ssl
Antoine Pitrou480a1242010-04-28 21:37:09 +00002169 def test_protocol_tlsv1(self):
2170 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002171 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002172 sys.stdout.write("\n")
Antoine Pitrou480a1242010-04-28 21:37:09 +00002173 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
2174 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
2175 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinner3de49192011-05-09 00:42:58 +02002176 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2177 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002178 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Barry Warsaw46ae0ef2011-10-28 16:52:17 -04002179 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2180 client_options=ssl.OP_NO_TLSv1)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002181
Antoine Pitrou2463e5f2013-03-28 22:24:43 +01002182 @skip_if_broken_ubuntu_ssl
2183 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2184 "TLS version 1.1 not supported.")
2185 def test_protocol_tlsv1_1(self):
2186 """Connecting to a TLSv1.1 server with various client options.
2187 Testing against older TLS versions."""
2188 if support.verbose:
2189 sys.stdout.write("\n")
2190 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, True)
2191 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2192 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
2193 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
2194 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2195 client_options=ssl.OP_NO_TLSv1_1)
2196
2197 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, True)
2198 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2199 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2200
2201
2202 @skip_if_broken_ubuntu_ssl
2203 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2204 "TLS version 1.2 not supported.")
2205 def test_protocol_tlsv1_2(self):
2206 """Connecting to a TLSv1.2 server with various client options.
2207 Testing against older TLS versions."""
2208 if support.verbose:
2209 sys.stdout.write("\n")
2210 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, True,
2211 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2212 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2213 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2214 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
2215 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
2216 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2217 client_options=ssl.OP_NO_TLSv1_2)
2218
2219 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, True)
2220 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2221 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2222 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2223 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
2224
Antoine Pitrou480a1242010-04-28 21:37:09 +00002225 def test_starttls(self):
2226 """Switching from clear text to encrypted and back again."""
2227 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 +00002228
Trent Nelson78520002008-04-10 20:54:35 +00002229 server = ThreadedEchoServer(CERTFILE,
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002230 ssl_version=ssl.PROTOCOL_TLSv1,
2231 starttls_server=True,
2232 chatty=True,
2233 connectionchatty=True)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002234 wrapped = False
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002235 with server:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002236 s = socket.socket()
2237 s.setblocking(1)
2238 s.connect((HOST, server.port))
2239 if support.verbose:
2240 sys.stdout.write("\n")
2241 for indata in msgs:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002242 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002243 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002244 " client: sending %r...\n" % indata)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002245 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002246 conn.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002247 outdata = conn.read()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002248 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002249 s.send(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002250 outdata = s.recv(1024)
Antoine Pitrou480a1242010-04-28 21:37:09 +00002251 msg = outdata.strip().lower()
2252 if indata == b"STARTTLS" and msg.startswith(b"ok"):
2253 # STARTTLS ok, switch to secure mode
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002254 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002255 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002256 " client: read %r from server, starting TLS...\n"
2257 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002258 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
2259 wrapped = True
Antoine Pitrou480a1242010-04-28 21:37:09 +00002260 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
2261 # ENDTLS ok, switch back to clear text
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002262 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002263 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002264 " client: read %r from server, ending TLS...\n"
2265 % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002266 s = conn.unwrap()
2267 wrapped = False
2268 else:
2269 if support.verbose:
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002270 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002271 " client: read %r from server\n" % msg)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002272 if support.verbose:
2273 sys.stdout.write(" client: closing connection.\n")
2274 if wrapped:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002275 conn.write(b"over\n")
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002276 else:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002277 s.send(b"over\n")
Bill Janssen6e027db2007-11-15 22:23:56 +00002278 if wrapped:
2279 conn.close()
2280 else:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002281 s.close()
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002282
Antoine Pitrou480a1242010-04-28 21:37:09 +00002283 def test_socketserver(self):
2284 """Using a SocketServer to create and manage SSL connections."""
Antoine Pitrouda232592013-02-05 21:20:51 +01002285 server = make_https_server(self, certfile=CERTFILE)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002286 # try to connect
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002287 if support.verbose:
2288 sys.stdout.write('\n')
2289 with open(CERTFILE, 'rb') as f:
2290 d1 = f.read()
2291 d2 = ''
2292 # now fetch the same data from the HTTPS server
2293 url = 'https://%s:%d/%s' % (
2294 HOST, server.port, os.path.split(CERTFILE)[1])
2295 f = urllib.request.urlopen(url)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002296 try:
Barry Warsaw820c1202008-06-12 04:06:45 +00002297 dlen = f.info().get("content-length")
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002298 if dlen and (int(dlen) > 0):
2299 d2 = f.read(int(dlen))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002300 if support.verbose:
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002301 sys.stdout.write(
2302 " client: read %d bytes from remote server '%s'\n"
2303 % (len(d2), server))
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002304 finally:
Antoine Pitrou803e6d62010-10-13 10:36:15 +00002305 f.close()
2306 self.assertEqual(d1, d2)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002307
Antoine Pitrou480a1242010-04-28 21:37:09 +00002308 def test_asyncore_server(self):
2309 """Check the example asyncore integration."""
2310 indata = "TEST MESSAGE of mixed case\n"
Trent Nelson6b240cd2008-04-10 20:12:06 +00002311
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002312 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002313 sys.stdout.write("\n")
2314
Antoine Pitrou480a1242010-04-28 21:37:09 +00002315 indata = b"FOO\n"
Trent Nelson78520002008-04-10 20:54:35 +00002316 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002317 with server:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002318 s = ssl.wrap_socket(socket.socket())
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002319 s.connect(('127.0.0.1', server.port))
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002320 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002321 sys.stdout.write(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002322 " client: sending %r...\n" % indata)
2323 s.write(indata)
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002324 outdata = s.read()
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002325 if support.verbose:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002326 sys.stdout.write(" client: read %r\n" % outdata)
Trent Nelson6b240cd2008-04-10 20:12:06 +00002327 if outdata != indata.lower():
Antoine Pitrou18c913e2010-04-27 10:59:39 +00002328 self.fail(
Antoine Pitrou480a1242010-04-28 21:37:09 +00002329 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2330 % (outdata[:20], len(outdata),
2331 indata[:20].lower(), len(indata)))
2332 s.write(b"over\n")
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002333 if support.verbose:
Trent Nelson6b240cd2008-04-10 20:12:06 +00002334 sys.stdout.write(" client: closing connection.\n")
2335 s.close()
Antoine Pitroued986362010-08-15 23:28:10 +00002336 if support.verbose:
2337 sys.stdout.write(" client: connection closed.\n")
Trent Nelson6b240cd2008-04-10 20:12:06 +00002338
Antoine Pitrou480a1242010-04-28 21:37:09 +00002339 def test_recv_send(self):
2340 """Test recv(), send() and friends."""
Bill Janssen58afe4c2008-09-08 16:45:19 +00002341 if support.verbose:
2342 sys.stdout.write("\n")
2343
2344 server = ThreadedEchoServer(CERTFILE,
2345 certreqs=ssl.CERT_NONE,
2346 ssl_version=ssl.PROTOCOL_TLSv1,
2347 cacerts=CERTFILE,
2348 chatty=True,
2349 connectionchatty=False)
Antoine Pitrou65a3f4b2011-12-21 16:52:40 +01002350 with server:
2351 s = ssl.wrap_socket(socket.socket(),
2352 server_side=False,
2353 certfile=CERTFILE,
2354 ca_certs=CERTFILE,
2355 cert_reqs=ssl.CERT_NONE,
2356 ssl_version=ssl.PROTOCOL_TLSv1)
2357 s.connect((HOST, server.port))
Bill Janssen58afe4c2008-09-08 16:45:19 +00002358 # helper methods for standardising recv* method signatures
2359 def _recv_into():
2360 b = bytearray(b"\0"*100)
2361 count = s.recv_into(b)
2362 return b[:count]
2363
2364 def _recvfrom_into():
2365 b = bytearray(b"\0"*100)
2366 count, addr = s.recvfrom_into(b)
2367 return b[:count]
2368
2369 # (name, method, whether to expect success, *args)
2370 send_methods = [
2371 ('send', s.send, True, []),
2372 ('sendto', s.sendto, False, ["some.address"]),
2373 ('sendall', s.sendall, True, []),
2374 ]
2375 recv_methods = [
2376 ('recv', s.recv, True, []),
2377 ('recvfrom', s.recvfrom, False, ["some.address"]),
2378 ('recv_into', _recv_into, True, []),
2379 ('recvfrom_into', _recvfrom_into, False, []),
2380 ]
2381 data_prefix = "PREFIX_"
2382
2383 for meth_name, send_meth, expect_success, args in send_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002384 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002385 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002386 send_meth(indata, *args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002387 outdata = s.read()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002388 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002389 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002390 "While sending with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002391 "<<{outdata:r}>> ({nout:d}) received; "
2392 "expected <<{indata:r}>> ({nin:d})\n".format(
2393 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002394 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002395 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002396 )
2397 )
2398 except ValueError as e:
2399 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002400 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002401 "Failed to send with method <<{name:s}>>; "
2402 "expected to succeed.\n".format(name=meth_name)
2403 )
2404 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002405 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002406 "Method <<{name:s}>> failed with unexpected "
2407 "exception message: {exp:s}\n".format(
2408 name=meth_name, exp=e
2409 )
2410 )
2411
2412 for meth_name, recv_meth, expect_success, args in recv_methods:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002413 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen58afe4c2008-09-08 16:45:19 +00002414 try:
Antoine Pitrou480a1242010-04-28 21:37:09 +00002415 s.send(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002416 outdata = recv_meth(*args)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002417 if outdata != indata.lower():
Georg Brandl89fad142010-03-14 10:23:39 +00002418 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002419 "While receiving with <<{name:s}>> bad data "
Antoine Pitrou480a1242010-04-28 21:37:09 +00002420 "<<{outdata:r}>> ({nout:d}) received; "
2421 "expected <<{indata:r}>> ({nin:d})\n".format(
2422 name=meth_name, outdata=outdata[:20],
Bill Janssen58afe4c2008-09-08 16:45:19 +00002423 nout=len(outdata),
Antoine Pitrou480a1242010-04-28 21:37:09 +00002424 indata=indata[:20], nin=len(indata)
Bill Janssen58afe4c2008-09-08 16:45:19 +00002425 )
2426 )
2427 except ValueError as e:
2428 if expect_success:
Georg Brandl89fad142010-03-14 10:23:39 +00002429 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002430 "Failed to receive with method <<{name:s}>>; "
2431 "expected to succeed.\n".format(name=meth_name)
2432 )
2433 if not str(e).startswith(meth_name):
Georg Brandl89fad142010-03-14 10:23:39 +00002434 self.fail(
Bill Janssen58afe4c2008-09-08 16:45:19 +00002435 "Method <<{name:s}>> failed with unexpected "
2436 "exception message: {exp:s}\n".format(
2437 name=meth_name, exp=e
2438 )
2439 )
2440 # consume data
2441 s.read()
2442
Nick Coghlan513886a2011-08-28 00:00:27 +10002443 # Make sure sendmsg et al are disallowed to avoid
2444 # inadvertent disclosure of data and/or corruption
2445 # of the encrypted data stream
2446 self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
2447 self.assertRaises(NotImplementedError, s.recvmsg, 100)
2448 self.assertRaises(NotImplementedError,
2449 s.recvmsg_into, bytearray(100))
2450
Antoine Pitrou480a1242010-04-28 21:37:09 +00002451 s.write(b"over\n")
Bill Janssen58afe4c2008-09-08 16:45:19 +00002452 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002453
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002454 def test_handshake_timeout(self):
2455 # Issue #5103: SSL handshake must respect the socket timeout
2456 server = socket.socket(socket.AF_INET)
2457 host = "127.0.0.1"
2458 port = support.bind_port(server)
2459 started = threading.Event()
2460 finish = False
2461
2462 def serve():
2463 server.listen(5)
2464 started.set()
2465 conns = []
2466 while not finish:
2467 r, w, e = select.select([server], [], [], 0.1)
2468 if server in r:
2469 # Let the socket hang around rather than having
2470 # it closed by garbage collection.
2471 conns.append(server.accept()[0])
Antoine Pitroud2eca372010-10-29 23:41:37 +00002472 for sock in conns:
2473 sock.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002474
2475 t = threading.Thread(target=serve)
2476 t.start()
2477 started.wait()
2478
2479 try:
Antoine Pitrou40f08742010-04-24 22:04:40 +00002480 try:
2481 c = socket.socket(socket.AF_INET)
2482 c.settimeout(0.2)
2483 c.connect((host, port))
2484 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002485 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002486 ssl.wrap_socket, c)
Antoine Pitrou40f08742010-04-24 22:04:40 +00002487 finally:
2488 c.close()
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002489 try:
2490 c = socket.socket(socket.AF_INET)
2491 c = ssl.wrap_socket(c)
2492 c.settimeout(0.2)
2493 # Will attempt handshake and time out
Antoine Pitrouc4df7842010-12-03 19:59:41 +00002494 self.assertRaisesRegex(socket.timeout, "timed out",
Ezio Melottied3a7d22010-12-01 02:32:32 +00002495 c.connect, (host, port))
Antoine Pitroud3f8ab82010-04-24 21:26:44 +00002496 finally:
2497 c.close()
2498 finally:
2499 finish = True
2500 t.join()
2501 server.close()
2502
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002503 def test_server_accept(self):
2504 # Issue #16357: accept() on a SSLSocket created through
2505 # SSLContext.wrap_socket().
2506 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2507 context.verify_mode = ssl.CERT_REQUIRED
2508 context.load_verify_locations(CERTFILE)
2509 context.load_cert_chain(CERTFILE)
2510 server = socket.socket(socket.AF_INET)
2511 host = "127.0.0.1"
2512 port = support.bind_port(server)
2513 server = context.wrap_socket(server, server_side=True)
2514
2515 evt = threading.Event()
2516 remote = None
2517 peer = None
2518 def serve():
2519 nonlocal remote, peer
2520 server.listen(5)
2521 # Block on the accept and wait on the connection to close.
2522 evt.set()
2523 remote, peer = server.accept()
2524 remote.recv(1)
2525
2526 t = threading.Thread(target=serve)
2527 t.start()
2528 # Client wait until server setup and perform a connect.
2529 evt.wait()
2530 client = context.wrap_socket(socket.socket())
2531 client.connect((host, port))
2532 client_addr = client.getsockname()
2533 client.close()
2534 t.join()
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002535 remote.close()
2536 server.close()
Antoine Pitrou5c89b4e2012-11-11 01:25:36 +01002537 # Sanity checks.
2538 self.assertIsInstance(remote, ssl.SSLSocket)
2539 self.assertEqual(peer, client_addr)
2540
Antoine Pitrou242db722013-05-01 20:52:07 +02002541 def test_getpeercert_enotconn(self):
2542 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2543 with context.wrap_socket(socket.socket()) as sock:
2544 with self.assertRaises(OSError) as cm:
2545 sock.getpeercert()
2546 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2547
2548 def test_do_handshake_enotconn(self):
2549 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2550 with context.wrap_socket(socket.socket()) as sock:
2551 with self.assertRaises(OSError) as cm:
2552 sock.do_handshake()
2553 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2554
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002555 def test_default_ciphers(self):
2556 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2557 try:
2558 # Force a set of weak ciphers on our client context
2559 context.set_ciphers("DES")
2560 except ssl.SSLError:
2561 self.skipTest("no DES cipher available")
2562 with ThreadedEchoServer(CERTFILE,
2563 ssl_version=ssl.PROTOCOL_SSLv23,
2564 chatty=False) as server:
Antoine Pitroue1ceb502013-01-12 21:54:44 +01002565 with context.wrap_socket(socket.socket()) as s:
Andrew Svetlov0832af62012-12-18 23:10:48 +02002566 with self.assertRaises(OSError):
Antoine Pitrou8f85f902012-01-03 22:46:48 +01002567 s.connect((HOST, server.port))
2568 self.assertIn("no shared cipher", str(server.conn_errors[0]))
2569
Antoine Pitroud6494802011-07-21 01:11:30 +02002570 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
2571 "'tls-unique' channel binding not available")
2572 def test_tls_unique_channel_binding(self):
2573 """Test tls-unique channel binding."""
2574 if support.verbose:
2575 sys.stdout.write("\n")
2576
2577 server = ThreadedEchoServer(CERTFILE,
2578 certreqs=ssl.CERT_NONE,
2579 ssl_version=ssl.PROTOCOL_TLSv1,
2580 cacerts=CERTFILE,
2581 chatty=True,
2582 connectionchatty=False)
Antoine Pitrou6b15c902011-12-21 16:54:45 +01002583 with server:
2584 s = ssl.wrap_socket(socket.socket(),
2585 server_side=False,
2586 certfile=CERTFILE,
2587 ca_certs=CERTFILE,
2588 cert_reqs=ssl.CERT_NONE,
2589 ssl_version=ssl.PROTOCOL_TLSv1)
2590 s.connect((HOST, server.port))
Antoine Pitroud6494802011-07-21 01:11:30 +02002591 # get the data
2592 cb_data = s.get_channel_binding("tls-unique")
2593 if support.verbose:
2594 sys.stdout.write(" got channel binding data: {0!r}\n"
2595 .format(cb_data))
2596
2597 # check if it is sane
2598 self.assertIsNotNone(cb_data)
2599 self.assertEqual(len(cb_data), 12) # True for TLSv1
2600
2601 # and compare with the peers version
2602 s.write(b"CB tls-unique\n")
2603 peer_data_repr = s.read().strip()
2604 self.assertEqual(peer_data_repr,
2605 repr(cb_data).encode("us-ascii"))
2606 s.close()
2607
2608 # now, again
2609 s = ssl.wrap_socket(socket.socket(),
2610 server_side=False,
2611 certfile=CERTFILE,
2612 ca_certs=CERTFILE,
2613 cert_reqs=ssl.CERT_NONE,
2614 ssl_version=ssl.PROTOCOL_TLSv1)
2615 s.connect((HOST, server.port))
2616 new_cb_data = s.get_channel_binding("tls-unique")
2617 if support.verbose:
2618 sys.stdout.write(" got another channel binding data: {0!r}\n"
2619 .format(new_cb_data))
2620 # is it really unique
2621 self.assertNotEqual(cb_data, new_cb_data)
2622 self.assertIsNotNone(cb_data)
2623 self.assertEqual(len(cb_data), 12) # True for TLSv1
2624 s.write(b"CB tls-unique\n")
2625 peer_data_repr = s.read().strip()
2626 self.assertEqual(peer_data_repr,
2627 repr(new_cb_data).encode("us-ascii"))
2628 s.close()
Bill Janssen58afe4c2008-09-08 16:45:19 +00002629
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002630 def test_compression(self):
2631 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2632 context.load_cert_chain(CERTFILE)
2633 stats = server_params_test(context, context,
2634 chatty=True, connectionchatty=True)
2635 if support.verbose:
2636 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
2637 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
2638
2639 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
2640 "ssl.OP_NO_COMPRESSION needed for this test")
2641 def test_compression_disabled(self):
2642 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2643 context.load_cert_chain(CERTFILE)
Antoine Pitrou8691bff2011-12-20 10:47:42 +01002644 context.options |= ssl.OP_NO_COMPRESSION
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002645 stats = server_params_test(context, context,
2646 chatty=True, connectionchatty=True)
2647 self.assertIs(stats['compression'], None)
2648
Antoine Pitrou0e576f12011-12-22 10:03:38 +01002649 def test_dh_params(self):
2650 # Check we can get a connection with ephemeral Diffie-Hellman
2651 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2652 context.load_cert_chain(CERTFILE)
2653 context.load_dh_params(DHFILE)
2654 context.set_ciphers("kEDH")
2655 stats = server_params_test(context, context,
2656 chatty=True, connectionchatty=True)
2657 cipher = stats["cipher"][0]
2658 parts = cipher.split("-")
2659 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
2660 self.fail("Non-DH cipher: " + cipher[0])
2661
Antoine Pitroud5d17eb2012-03-22 00:23:03 +01002662 def test_selected_npn_protocol(self):
2663 # selected_npn_protocol() is None unless NPN is used
2664 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2665 context.load_cert_chain(CERTFILE)
2666 stats = server_params_test(context, context,
2667 chatty=True, connectionchatty=True)
2668 self.assertIs(stats['client_npn_protocol'], None)
2669
2670 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
2671 def test_npn_protocols(self):
2672 server_protocols = ['http/1.1', 'spdy/2']
2673 protocol_tests = [
2674 (['http/1.1', 'spdy/2'], 'http/1.1'),
2675 (['spdy/2', 'http/1.1'], 'http/1.1'),
2676 (['spdy/2', 'test'], 'spdy/2'),
2677 (['abc', 'def'], 'abc')
2678 ]
2679 for client_protocols, expected in protocol_tests:
2680 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2681 server_context.load_cert_chain(CERTFILE)
2682 server_context.set_npn_protocols(server_protocols)
2683 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2684 client_context.load_cert_chain(CERTFILE)
2685 client_context.set_npn_protocols(client_protocols)
2686 stats = server_params_test(client_context, server_context,
2687 chatty=True, connectionchatty=True)
2688
2689 msg = "failed trying %s (s) and %s (c).\n" \
2690 "was expecting %s, but got %%s from the %%s" \
2691 % (str(server_protocols), str(client_protocols),
2692 str(expected))
2693 client_result = stats['client_npn_protocol']
2694 self.assertEqual(client_result, expected, msg % (client_result, "client"))
2695 server_result = stats['server_npn_protocols'][-1] \
2696 if len(stats['server_npn_protocols']) else 'nothing'
2697 self.assertEqual(server_result, expected, msg % (server_result, "server"))
2698
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002699 def sni_contexts(self):
2700 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2701 server_context.load_cert_chain(SIGNED_CERTFILE)
2702 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2703 other_context.load_cert_chain(SIGNED_CERTFILE2)
2704 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2705 client_context.verify_mode = ssl.CERT_REQUIRED
2706 client_context.load_verify_locations(SIGNING_CA)
2707 return server_context, other_context, client_context
2708
2709 def check_common_name(self, stats, name):
2710 cert = stats['peercert']
2711 self.assertIn((('commonName', name),), cert['subject'])
2712
2713 @needs_sni
2714 def test_sni_callback(self):
2715 calls = []
2716 server_context, other_context, client_context = self.sni_contexts()
2717
2718 def servername_cb(ssl_sock, server_name, initial_context):
2719 calls.append((server_name, initial_context))
Antoine Pitrou50b24d02013-04-11 20:48:42 +02002720 if server_name is not None:
2721 ssl_sock.context = other_context
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002722 server_context.set_servername_callback(servername_cb)
2723
2724 stats = server_params_test(client_context, server_context,
2725 chatty=True,
2726 sni_name='supermessage')
2727 # The hostname was fetched properly, and the certificate was
2728 # changed for the connection.
2729 self.assertEqual(calls, [("supermessage", server_context)])
2730 # CERTFILE4 was selected
2731 self.check_common_name(stats, 'fakehostname')
2732
Antoine Pitrou50b24d02013-04-11 20:48:42 +02002733 calls = []
2734 # The callback is called with server_name=None
2735 stats = server_params_test(client_context, server_context,
2736 chatty=True,
2737 sni_name=None)
2738 self.assertEqual(calls, [(None, server_context)])
2739 self.check_common_name(stats, 'localhost')
2740
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002741 # Check disabling the callback
2742 calls = []
2743 server_context.set_servername_callback(None)
2744
2745 stats = server_params_test(client_context, server_context,
2746 chatty=True,
2747 sni_name='notfunny')
2748 # Certificate didn't change
2749 self.check_common_name(stats, 'localhost')
2750 self.assertEqual(calls, [])
2751
2752 @needs_sni
2753 def test_sni_callback_alert(self):
2754 # Returning a TLS alert is reflected to the connecting client
2755 server_context, other_context, client_context = self.sni_contexts()
2756
2757 def cb_returning_alert(ssl_sock, server_name, initial_context):
2758 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
2759 server_context.set_servername_callback(cb_returning_alert)
2760
2761 with self.assertRaises(ssl.SSLError) as cm:
2762 stats = server_params_test(client_context, server_context,
2763 chatty=False,
2764 sni_name='supermessage')
2765 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
2766
2767 @needs_sni
2768 def test_sni_callback_raising(self):
2769 # Raising fails the connection with a TLS handshake failure alert.
2770 server_context, other_context, client_context = self.sni_contexts()
2771
2772 def cb_raising(ssl_sock, server_name, initial_context):
2773 1/0
2774 server_context.set_servername_callback(cb_raising)
2775
2776 with self.assertRaises(ssl.SSLError) as cm, \
2777 support.captured_stderr() as stderr:
2778 stats = server_params_test(client_context, server_context,
2779 chatty=False,
2780 sni_name='supermessage')
2781 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
2782 self.assertIn("ZeroDivisionError", stderr.getvalue())
2783
2784 @needs_sni
2785 def test_sni_callback_wrong_return_type(self):
2786 # Returning the wrong return type terminates the TLS connection
2787 # with an internal error alert.
2788 server_context, other_context, client_context = self.sni_contexts()
2789
2790 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
2791 return "foo"
2792 server_context.set_servername_callback(cb_wrong_return_type)
2793
2794 with self.assertRaises(ssl.SSLError) as cm, \
2795 support.captured_stderr() as stderr:
2796 stats = server_params_test(client_context, server_context,
2797 chatty=False,
2798 sni_name='supermessage')
2799 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
2800 self.assertIn("TypeError", stderr.getvalue())
2801
Antoine Pitrou60a26e02013-07-20 19:35:16 +02002802 def test_read_write_after_close_raises_valuerror(self):
2803 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2804 context.verify_mode = ssl.CERT_REQUIRED
2805 context.load_verify_locations(CERTFILE)
2806 context.load_cert_chain(CERTFILE)
2807 server = ThreadedEchoServer(context=context, chatty=False)
2808
2809 with server:
2810 s = context.wrap_socket(socket.socket())
2811 s.connect((HOST, server.port))
2812 s.close()
2813
2814 self.assertRaises(ValueError, s.read, 1024)
Antoine Pitrou28940732013-07-20 19:36:15 +02002815 self.assertRaises(ValueError, s.write, b'hello')
Antoine Pitrou60a26e02013-07-20 19:35:16 +02002816
Antoine Pitrou8abdb8a2011-12-20 10:13:40 +01002817
Thomas Woutersed03b412007-08-28 21:37:11 +00002818def test_main(verbose=False):
Antoine Pitrou15cee622010-08-04 16:45:21 +00002819 if support.verbose:
2820 plats = {
2821 'Linux': platform.linux_distribution,
2822 'Mac': platform.mac_ver,
2823 'Windows': platform.win32_ver,
2824 }
2825 for name, func in plats.items():
2826 plat = func()
2827 if plat and plat[0]:
2828 plat = '%s %r' % (name, plat)
2829 break
2830 else:
2831 plat = repr(platform.platform())
2832 print("test_ssl: testing with %r %r" %
2833 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
2834 print(" under %s" % plat)
Antoine Pitroud5323212010-10-22 18:19:07 +00002835 print(" HAS_SNI = %r" % ssl.HAS_SNI)
Antoine Pitrou609ef012013-03-29 18:09:06 +01002836 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
2837 try:
2838 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
2839 except AttributeError:
2840 pass
Antoine Pitrou15cee622010-08-04 16:45:21 +00002841
Antoine Pitrou152efa22010-05-16 18:19:27 +00002842 for filename in [
2843 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
2844 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01002845 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
Antoine Pitrou152efa22010-05-16 18:19:27 +00002846 BADCERT, BADKEY, EMPTYCERT]:
2847 if not os.path.exists(filename):
2848 raise support.TestFailed("Can't read certificate file %r" % filename)
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002849
Antoine Pitrou3b36fb12012-06-22 21:11:52 +02002850 tests = [ContextTests, BasicSocketTests, SSLErrorTests]
Thomas Woutersed03b412007-08-28 21:37:11 +00002851
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002852 if support.is_resource_enabled('network'):
Bill Janssen6e027db2007-11-15 22:23:56 +00002853 tests.append(NetworkedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00002854
Thomas Wouters1b7f8912007-09-19 03:06:30 +00002855 if _have_threads:
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002856 thread_info = support.threading_setup()
Antoine Pitroudb5012a2013-01-12 22:00:09 +01002857 if thread_info:
Bill Janssen6e027db2007-11-15 22:23:56 +00002858 tests.append(ThreadedTests)
Thomas Woutersed03b412007-08-28 21:37:11 +00002859
Antoine Pitrou480a1242010-04-28 21:37:09 +00002860 try:
2861 support.run_unittest(*tests)
2862 finally:
2863 if _have_threads:
2864 support.threading_cleanup(*thread_info)
Thomas Woutersed03b412007-08-28 21:37:11 +00002865
2866if __name__ == "__main__":
2867 test_main()