blob: cfc03e343c7d6b6d082f1708373a00afcfab440f [file] [log] [blame]
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001# -*- coding: utf-8 -*-
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00002# Test the support for SSL and sockets
3
4import sys
5import unittest
Benjamin Petersondaeb9252014-08-20 14:14:50 -05006from test import test_support as support
Nick Coghlandbcd4572016-03-20 22:39:15 +10007from test.script_helper import assert_python_ok
Bill Janssen934b16d2008-06-28 22:19:33 +00008import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009import socket
Bill Janssen934b16d2008-06-28 22:19:33 +000010import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000011import time
Benjamin Petersondaeb9252014-08-20 14:14:50 -050012import datetime
Antoine Pitroub558f172010-04-23 23:25:45 +000013import gc
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000014import os
Antoine Pitroub558f172010-04-23 23:25:45 +000015import errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000016import pprint
Benjamin Petersondaeb9252014-08-20 14:14:50 -050017import tempfile
Benjamin Petersonfcfb18e2014-11-23 11:42:45 -060018import urllib2
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000019import traceback
Antoine Pitroudfb299b2010-04-23 22:54:59 +000020import weakref
Antoine Pitroud75efd92010-08-04 17:38:33 +000021import platform
Benjamin Petersondaeb9252014-08-20 14:14:50 -050022import functools
23from contextlib import closing
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000024
Benjamin Petersondaeb9252014-08-20 14:14:50 -050025ssl = support.import_module("ssl")
Bill Janssen296a59d2007-09-16 22:06:00 +000026
Benjamin Petersondaeb9252014-08-20 14:14:50 -050027PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
28HOST = support.HOST
Christian Heimesc2fc7c42016-09-05 23:37:13 +020029IS_LIBRESSL = ssl.OPENSSL_VERSION.startswith('LibreSSL')
30IS_OPENSSL_1_1 = not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0)
31
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000032
Benjamin Petersondaeb9252014-08-20 14:14:50 -050033def data_file(*name):
34 return os.path.join(os.path.dirname(__file__), *name)
35
36# The custom key and certificate files used in test_ssl are generated
37# using Lib/test/make_ssl_certs.py.
38# Other certificates are simply fetched from the Internet servers they
39# are meant to authenticate.
40
41CERTFILE = data_file("keycert.pem")
42BYTES_CERTFILE = CERTFILE.encode(sys.getfilesystemencoding())
43ONLYCERT = data_file("ssl_cert.pem")
44ONLYKEY = data_file("ssl_key.pem")
45BYTES_ONLYCERT = ONLYCERT.encode(sys.getfilesystemencoding())
46BYTES_ONLYKEY = ONLYKEY.encode(sys.getfilesystemencoding())
47CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
48ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
49KEY_PASSWORD = "somepass"
50CAPATH = data_file("capath")
51BYTES_CAPATH = CAPATH.encode(sys.getfilesystemencoding())
52CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
53CAFILE_CACERT = data_file("capath", "5ed36f99.0")
54
55
56# empty CRL
57CRLFILE = data_file("revocation.crl")
58
59# Two keys and certs signed by the same CA (for SNI tests)
60SIGNED_CERTFILE = data_file("keycert3.pem")
61SIGNED_CERTFILE2 = data_file("keycert4.pem")
62SIGNING_CA = data_file("pycacert.pem")
Christian Heimes6663eb62016-09-06 23:25:35 +020063# cert with all kinds of subject alt names
64ALLSANFILE = data_file("allsans.pem")
Benjamin Petersondaeb9252014-08-20 14:14:50 -050065
Martin Panter71202bb2016-01-15 00:25:29 +000066REMOTE_HOST = "self-signed.pythontest.net"
67REMOTE_ROOT_CERT = data_file("selfsigned_pythontestdotnet.pem")
Benjamin Petersondaeb9252014-08-20 14:14:50 -050068
69EMPTYCERT = data_file("nullcert.pem")
70BADCERT = data_file("badcert.pem")
Martin Panterfd8e8502016-01-30 02:36:00 +000071NONEXISTINGCERT = data_file("XXXnonexisting.pem")
Benjamin Petersondaeb9252014-08-20 14:14:50 -050072BADKEY = data_file("badkey.pem")
73NOKIACERT = data_file("nokia.pem")
74NULLBYTECERT = data_file("nullbytecert.pem")
75
Benjamin Petersondf11d4c2015-04-02 00:04:06 -040076DHFILE = data_file("dh1024.pem")
Benjamin Petersondaeb9252014-08-20 14:14:50 -050077BYTES_DHFILE = DHFILE.encode(sys.getfilesystemencoding())
78
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000079
Neal Norwitz3e533c22007-08-27 01:03:18 +000080def handle_error(prefix):
81 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersondaeb9252014-08-20 14:14:50 -050082 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +000083 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000084
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000085
86class BasicTests(unittest.TestCase):
87
Antoine Pitrou3945c862010-04-28 21:11:01 +000088 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000089 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000090 try:
91 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
92 except IOError, e:
93 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
94 pass
95 else:
96 raise
97 try:
98 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
99 except IOError, e:
100 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
101 pass
102 else:
103 raise
Benjamin Peterson2f334562014-10-01 23:53:01 -0400104
105
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500106def can_clear_options():
107 # 0.9.8m or higher
108 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
109
110def no_sslv2_implies_sslv3_hello():
111 # 0.9.7h or higher
112 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
113
114def have_verify_flags():
115 # 0.9.8 or higher
116 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
117
118def utc_offset(): #NOTE: ignore issues like #1647654
119 # local time = utc time + utc offset
120 if time.daylight and time.localtime().tm_isdst > 0:
121 return -time.altzone # seconds
122 return -time.timezone
123
124def asn1time(cert_time):
125 # Some versions of OpenSSL ignore seconds, see #18207
126 # 0.9.8.i
127 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
128 fmt = "%b %d %H:%M:%S %Y GMT"
129 dt = datetime.datetime.strptime(cert_time, fmt)
130 dt = dt.replace(second=0)
131 cert_time = dt.strftime(fmt)
132 # %d adds leading zero but ASN1_TIME_print() uses leading space
133 if cert_time[4] == "0":
134 cert_time = cert_time[:4] + " " + cert_time[5:]
135
136 return cert_time
Neal Norwitz3e533c22007-08-27 01:03:18 +0000137
Antoine Pitroud75efd92010-08-04 17:38:33 +0000138# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
139def skip_if_broken_ubuntu_ssl(func):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200140 if hasattr(ssl, 'PROTOCOL_SSLv2'):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200141 @functools.wraps(func)
142 def f(*args, **kwargs):
143 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500144 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
145 except ssl.SSLError:
Victor Stinnerb1241f92011-05-10 01:52:03 +0200146 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500147 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200148 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
149 return func(*args, **kwargs)
150 return f
151 else:
152 return func
Antoine Pitroud75efd92010-08-04 17:38:33 +0000153
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500154needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
155
Antoine Pitroud75efd92010-08-04 17:38:33 +0000156
157class BasicSocketTests(unittest.TestCase):
158
Antoine Pitrou3945c862010-04-28 21:11:01 +0000159 def test_constants(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000160 ssl.CERT_NONE
161 ssl.CERT_OPTIONAL
162 ssl.CERT_REQUIRED
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500163 ssl.OP_CIPHER_SERVER_PREFERENCE
164 ssl.OP_SINGLE_DH_USE
165 if ssl.HAS_ECDH:
166 ssl.OP_SINGLE_ECDH_USE
167 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
168 ssl.OP_NO_COMPRESSION
169 self.assertIn(ssl.HAS_SNI, {True, False})
170 self.assertIn(ssl.HAS_ECDH, {True, False})
Christian Heimesb9a860f2017-09-07 22:31:17 -0700171 ssl.OP_NO_SSLv2
172 ssl.OP_NO_SSLv3
173 ssl.OP_NO_TLSv1
174 ssl.OP_NO_TLSv1_3
175 if ssl.OPENSSL_VERSION_INFO >= (1, 0, 1):
176 ssl.OP_NO_TLSv1_1
177 ssl.OP_NO_TLSv1_2
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500178
Antoine Pitrou3945c862010-04-28 21:11:01 +0000179 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000180 v = ssl.RAND_status()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500181 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000182 sys.stdout.write("\n RAND_status is %d (%s)\n"
183 % (v, (v and "sufficient randomness") or
184 "insufficient randomness"))
Victor Stinner7c906672015-01-06 13:53:37 +0100185 if hasattr(ssl, 'RAND_egd'):
186 self.assertRaises(TypeError, ssl.RAND_egd, 1)
187 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000188 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000189
Antoine Pitrou3945c862010-04-28 21:11:01 +0000190 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000191 # note that this uses an 'unofficial' function in _ssl.c,
192 # provided solely for this test, to exercise the certificate
193 # parsing code
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500194 p = ssl._ssl._test_decode_cert(CERTFILE)
195 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000196 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500197 self.assertEqual(p['issuer'],
198 ((('countryName', 'XY'),),
199 (('localityName', 'Castle Anthrax'),),
200 (('organizationName', 'Python Software Foundation'),),
201 (('commonName', 'localhost'),))
202 )
203 # Note the next three asserts will fail if the keys are regenerated
204 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
205 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
206 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200207 self.assertEqual(p['subject'],
Antoine Pitrou60982912013-02-16 21:39:28 +0100208 ((('countryName', 'XY'),),
209 (('localityName', 'Castle Anthrax'),),
210 (('organizationName', 'Python Software Foundation'),),
211 (('commonName', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200212 )
Antoine Pitrou60982912013-02-16 21:39:28 +0100213 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200214 # Issue #13034: the subjectAltName in some certificates
215 # (notably projects.developer.nokia.com:443) wasn't parsed
216 p = ssl._ssl._test_decode_cert(NOKIACERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500217 if support.verbose:
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200218 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
219 self.assertEqual(p['subjectAltName'],
220 (('DNS', 'projects.developer.nokia.com'),
221 ('DNS', 'projects.forum.nokia.com'))
222 )
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500223 # extra OCSP and AIA fields
224 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
225 self.assertEqual(p['caIssuers'],
226 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
227 self.assertEqual(p['crlDistributionPoints'],
228 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000229
Christian Heimes88b174c2013-08-17 00:54:47 +0200230 def test_parse_cert_CVE_2013_4238(self):
231 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500232 if support.verbose:
Christian Heimes88b174c2013-08-17 00:54:47 +0200233 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
234 subject = ((('countryName', 'US'),),
235 (('stateOrProvinceName', 'Oregon'),),
236 (('localityName', 'Beaverton'),),
237 (('organizationName', 'Python Software Foundation'),),
238 (('organizationalUnitName', 'Python Core Development'),),
239 (('commonName', 'null.python.org\x00example.org'),),
240 (('emailAddress', 'python-dev@python.org'),))
241 self.assertEqual(p['subject'], subject)
242 self.assertEqual(p['issuer'], subject)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500243 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
Christian Heimesf869a942013-08-25 14:12:41 +0200244 san = (('DNS', 'altnull.python.org\x00example.com'),
245 ('email', 'null@python.org\x00user@example.org'),
246 ('URI', 'http://null.python.org\x00http://example.org'),
247 ('IP Address', '192.0.2.1'),
248 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
249 else:
250 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
251 san = (('DNS', 'altnull.python.org\x00example.com'),
252 ('email', 'null@python.org\x00user@example.org'),
253 ('URI', 'http://null.python.org\x00http://example.org'),
254 ('IP Address', '192.0.2.1'),
255 ('IP Address', '<invalid>'))
256
257 self.assertEqual(p['subjectAltName'], san)
Christian Heimes88b174c2013-08-17 00:54:47 +0200258
Christian Heimes6663eb62016-09-06 23:25:35 +0200259 def test_parse_all_sans(self):
260 p = ssl._ssl._test_decode_cert(ALLSANFILE)
261 self.assertEqual(p['subjectAltName'],
262 (
263 ('DNS', 'allsans'),
264 ('othername', '<unsupported>'),
265 ('othername', '<unsupported>'),
266 ('email', 'user@example.org'),
267 ('DNS', 'www.example.org'),
268 ('DirName',
269 ((('countryName', 'XY'),),
270 (('localityName', 'Castle Anthrax'),),
271 (('organizationName', 'Python Software Foundation'),),
272 (('commonName', 'dirname example'),))),
273 ('URI', 'https://www.python.org/'),
274 ('IP Address', '127.0.0.1'),
275 ('IP Address', '0:0:0:0:0:0:0:1\n'),
276 ('Registered ID', '1.2.3.4.5')
277 )
278 )
279
Antoine Pitrou3945c862010-04-28 21:11:01 +0000280 def test_DER_to_PEM(self):
Martin Panter71202bb2016-01-15 00:25:29 +0000281 with open(CAFILE_CACERT, 'r') as f:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000282 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000283 d1 = ssl.PEM_cert_to_DER_cert(pem)
284 p2 = ssl.DER_cert_to_PEM_cert(d1)
285 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000286 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000287 if not p2.startswith(ssl.PEM_HEADER + '\n'):
288 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
289 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
290 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000291
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000292 def test_openssl_version(self):
293 n = ssl.OPENSSL_VERSION_NUMBER
294 t = ssl.OPENSSL_VERSION_INFO
295 s = ssl.OPENSSL_VERSION
296 self.assertIsInstance(n, (int, long))
297 self.assertIsInstance(t, tuple)
298 self.assertIsInstance(s, str)
299 # Some sanity checks follow
300 # >= 0.9
301 self.assertGreaterEqual(n, 0x900000)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400302 # < 3.0
303 self.assertLess(n, 0x30000000)
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000304 major, minor, fix, patch, status = t
305 self.assertGreaterEqual(major, 0)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400306 self.assertLess(major, 3)
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000307 self.assertGreaterEqual(minor, 0)
308 self.assertLess(minor, 256)
309 self.assertGreaterEqual(fix, 0)
310 self.assertLess(fix, 256)
311 self.assertGreaterEqual(patch, 0)
Ned Deilyfa119782015-02-05 17:19:11 +1100312 self.assertLessEqual(patch, 63)
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000313 self.assertGreaterEqual(status, 0)
314 self.assertLessEqual(status, 15)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400315 # Version string as returned by {Open,Libre}SSL, the format might change
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200316 if IS_LIBRESSL:
317 self.assertTrue(s.startswith("LibreSSL {:d}".format(major)),
318 (s, t, hex(n)))
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400319 else:
320 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
321 (s, t))
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000322
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500323 @support.cpython_only
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000324 def test_refcycle(self):
325 # Issue #7943: an SSL object doesn't create reference cycles with
326 # itself.
327 s = socket.socket(socket.AF_INET)
328 ss = ssl.wrap_socket(s)
329 wr = weakref.ref(ss)
330 del ss
331 self.assertEqual(wr(), None)
332
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000333 def test_wrapped_unconnected(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500334 # Methods on an unconnected SSLSocket propagate the original
335 # socket.error raise by the underlying socket object.
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000336 s = socket.socket(socket.AF_INET)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500337 with closing(ssl.wrap_socket(s)) as ss:
338 self.assertRaises(socket.error, ss.recv, 1)
339 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
340 self.assertRaises(socket.error, ss.recvfrom, 1)
341 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
342 self.assertRaises(socket.error, ss.send, b'x')
343 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
344
345 def test_timeout(self):
346 # Issue #8524: when creating an SSL socket, the timeout of the
347 # original socket should be retained.
348 for timeout in (None, 0.0, 5.0):
349 s = socket.socket(socket.AF_INET)
350 s.settimeout(timeout)
351 with closing(ssl.wrap_socket(s)) as ss:
352 self.assertEqual(timeout, ss.gettimeout())
353
354 def test_errors(self):
355 sock = socket.socket()
356 self.assertRaisesRegexp(ValueError,
357 "certfile must be specified",
358 ssl.wrap_socket, sock, keyfile=CERTFILE)
359 self.assertRaisesRegexp(ValueError,
360 "certfile must be specified for server-side operations",
361 ssl.wrap_socket, sock, server_side=True)
362 self.assertRaisesRegexp(ValueError,
363 "certfile must be specified for server-side operations",
364 ssl.wrap_socket, sock, server_side=True, certfile="")
365 with closing(ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)) as s:
366 self.assertRaisesRegexp(ValueError, "can't connect in server-side mode",
367 s.connect, (HOST, 8080))
368 with self.assertRaises(IOError) as cm:
369 with closing(socket.socket()) as sock:
Martin Panterfd8e8502016-01-30 02:36:00 +0000370 ssl.wrap_socket(sock, certfile=NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500371 self.assertEqual(cm.exception.errno, errno.ENOENT)
372 with self.assertRaises(IOError) as cm:
373 with closing(socket.socket()) as sock:
Martin Panterfd8e8502016-01-30 02:36:00 +0000374 ssl.wrap_socket(sock,
375 certfile=CERTFILE, keyfile=NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500376 self.assertEqual(cm.exception.errno, errno.ENOENT)
377 with self.assertRaises(IOError) as cm:
378 with closing(socket.socket()) as sock:
Martin Panterfd8e8502016-01-30 02:36:00 +0000379 ssl.wrap_socket(sock,
380 certfile=NONEXISTINGCERT, keyfile=NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500381 self.assertEqual(cm.exception.errno, errno.ENOENT)
382
Martin Panter886aba42016-02-01 21:58:11 +0000383 def bad_cert_test(self, certfile):
384 """Check that trying to use the given client certificate fails"""
385 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
386 certfile)
387 sock = socket.socket()
388 self.addCleanup(sock.close)
389 with self.assertRaises(ssl.SSLError):
390 ssl.wrap_socket(sock,
391 certfile=certfile,
392 ssl_version=ssl.PROTOCOL_TLSv1)
393
394 def test_empty_cert(self):
395 """Wrapping with an empty cert file"""
396 self.bad_cert_test("nullcert.pem")
397
398 def test_malformed_cert(self):
399 """Wrapping with a badly formatted certificate (syntax error)"""
400 self.bad_cert_test("badcert.pem")
401
402 def test_malformed_key(self):
403 """Wrapping with a badly formatted key (syntax error)"""
404 self.bad_cert_test("badkey.pem")
405
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500406 def test_match_hostname(self):
407 def ok(cert, hostname):
408 ssl.match_hostname(cert, hostname)
409 def fail(cert, hostname):
410 self.assertRaises(ssl.CertificateError,
411 ssl.match_hostname, cert, hostname)
412
413 cert = {'subject': ((('commonName', 'example.com'),),)}
414 ok(cert, 'example.com')
415 ok(cert, 'ExAmple.cOm')
416 fail(cert, 'www.example.com')
417 fail(cert, '.example.com')
418 fail(cert, 'example.org')
419 fail(cert, 'exampleXcom')
420
421 cert = {'subject': ((('commonName', '*.a.com'),),)}
422 ok(cert, 'foo.a.com')
423 fail(cert, 'bar.foo.a.com')
424 fail(cert, 'a.com')
425 fail(cert, 'Xa.com')
426 fail(cert, '.a.com')
427
428 # only match one left-most wildcard
429 cert = {'subject': ((('commonName', 'f*.com'),),)}
430 ok(cert, 'foo.com')
431 ok(cert, 'f.com')
432 fail(cert, 'bar.com')
433 fail(cert, 'foo.a.com')
434 fail(cert, 'bar.foo.com')
435
436 # NULL bytes are bad, CVE-2013-4073
437 cert = {'subject': ((('commonName',
438 'null.python.org\x00example.org'),),)}
439 ok(cert, 'null.python.org\x00example.org') # or raise an error?
440 fail(cert, 'example.org')
441 fail(cert, 'null.python.org')
442
443 # error cases with wildcards
444 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
445 fail(cert, 'bar.foo.a.com')
446 fail(cert, 'a.com')
447 fail(cert, 'Xa.com')
448 fail(cert, '.a.com')
449
450 cert = {'subject': ((('commonName', 'a.*.com'),),)}
451 fail(cert, 'a.foo.com')
452 fail(cert, 'a..com')
453 fail(cert, 'a.com')
454
455 # wildcard doesn't match IDNA prefix 'xn--'
456 idna = u'püthon.python.org'.encode("idna").decode("ascii")
457 cert = {'subject': ((('commonName', idna),),)}
458 ok(cert, idna)
459 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
460 fail(cert, idna)
461 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
462 fail(cert, idna)
463
464 # wildcard in first fragment and IDNA A-labels in sequent fragments
465 # are supported.
466 idna = u'www*.pythön.org'.encode("idna").decode("ascii")
467 cert = {'subject': ((('commonName', idna),),)}
468 ok(cert, u'www.pythön.org'.encode("idna").decode("ascii"))
469 ok(cert, u'www1.pythön.org'.encode("idna").decode("ascii"))
470 fail(cert, u'ftp.pythön.org'.encode("idna").decode("ascii"))
471 fail(cert, u'pythön.org'.encode("idna").decode("ascii"))
472
473 # Slightly fake real-world example
474 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
475 'subject': ((('commonName', 'linuxfrz.org'),),),
476 'subjectAltName': (('DNS', 'linuxfr.org'),
477 ('DNS', 'linuxfr.com'),
478 ('othername', '<unsupported>'))}
479 ok(cert, 'linuxfr.org')
480 ok(cert, 'linuxfr.com')
481 # Not a "DNS" entry
482 fail(cert, '<unsupported>')
483 # When there is a subjectAltName, commonName isn't used
484 fail(cert, 'linuxfrz.org')
485
486 # A pristine real-world example
487 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
488 'subject': ((('countryName', 'US'),),
489 (('stateOrProvinceName', 'California'),),
490 (('localityName', 'Mountain View'),),
491 (('organizationName', 'Google Inc'),),
492 (('commonName', 'mail.google.com'),))}
493 ok(cert, 'mail.google.com')
494 fail(cert, 'gmail.com')
495 # Only commonName is considered
496 fail(cert, 'California')
497
498 # Neither commonName nor subjectAltName
499 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
500 'subject': ((('countryName', 'US'),),
501 (('stateOrProvinceName', 'California'),),
502 (('localityName', 'Mountain View'),),
503 (('organizationName', 'Google Inc'),))}
504 fail(cert, 'mail.google.com')
505
506 # No DNS entry in subjectAltName but a commonName
507 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
508 'subject': ((('countryName', 'US'),),
509 (('stateOrProvinceName', 'California'),),
510 (('localityName', 'Mountain View'),),
511 (('commonName', 'mail.google.com'),)),
512 'subjectAltName': (('othername', 'blabla'), )}
513 ok(cert, 'mail.google.com')
514
515 # No DNS entry subjectAltName and no commonName
516 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
517 'subject': ((('countryName', 'US'),),
518 (('stateOrProvinceName', 'California'),),
519 (('localityName', 'Mountain View'),),
520 (('organizationName', 'Google Inc'),)),
521 'subjectAltName': (('othername', 'blabla'),)}
522 fail(cert, 'google.com')
523
524 # Empty cert / no cert
525 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
526 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
527
528 # Issue #17980: avoid denials of service by refusing more than one
529 # wildcard per fragment.
530 cert = {'subject': ((('commonName', 'a*b.com'),),)}
531 ok(cert, 'axxb.com')
532 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
533 fail(cert, 'axxb.com')
534 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
535 with self.assertRaises(ssl.CertificateError) as cm:
536 ssl.match_hostname(cert, 'axxbxxc.com')
537 self.assertIn("too many wildcards", str(cm.exception))
538
539 def test_server_side(self):
540 # server_hostname doesn't work for server sockets
541 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
542 with closing(socket.socket()) as sock:
543 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
544 server_hostname="some.hostname")
545
546 def test_unknown_channel_binding(self):
547 # should raise ValueError for unknown type
548 s = socket.socket(socket.AF_INET)
549 with closing(ssl.wrap_socket(s)) as ss:
550 with self.assertRaises(ValueError):
551 ss.get_channel_binding("unknown-type")
552
553 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
554 "'tls-unique' channel binding not available")
555 def test_tls_unique_channel_binding(self):
556 # unconnected should return None for known type
557 s = socket.socket(socket.AF_INET)
558 with closing(ssl.wrap_socket(s)) as ss:
559 self.assertIsNone(ss.get_channel_binding("tls-unique"))
560 # the same for server-side
561 s = socket.socket(socket.AF_INET)
562 with closing(ssl.wrap_socket(s, server_side=True, certfile=CERTFILE)) as ss:
563 self.assertIsNone(ss.get_channel_binding("tls-unique"))
564
565 def test_get_default_verify_paths(self):
566 paths = ssl.get_default_verify_paths()
567 self.assertEqual(len(paths), 6)
568 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
569
570 with support.EnvironmentVarGuard() as env:
571 env["SSL_CERT_DIR"] = CAPATH
572 env["SSL_CERT_FILE"] = CERTFILE
573 paths = ssl.get_default_verify_paths()
574 self.assertEqual(paths.cafile, CERTFILE)
575 self.assertEqual(paths.capath, CAPATH)
576
577 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
578 def test_enum_certificates(self):
579 self.assertTrue(ssl.enum_certificates("CA"))
580 self.assertTrue(ssl.enum_certificates("ROOT"))
581
582 self.assertRaises(TypeError, ssl.enum_certificates)
583 self.assertRaises(WindowsError, ssl.enum_certificates, "")
584
585 trust_oids = set()
586 for storename in ("CA", "ROOT"):
587 store = ssl.enum_certificates(storename)
588 self.assertIsInstance(store, list)
589 for element in store:
590 self.assertIsInstance(element, tuple)
591 self.assertEqual(len(element), 3)
592 cert, enc, trust = element
593 self.assertIsInstance(cert, bytes)
594 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
595 self.assertIsInstance(trust, (set, bool))
596 if isinstance(trust, set):
597 trust_oids.update(trust)
598
599 serverAuth = "1.3.6.1.5.5.7.3.1"
600 self.assertIn(serverAuth, trust_oids)
601
602 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
603 def test_enum_crls(self):
604 self.assertTrue(ssl.enum_crls("CA"))
605 self.assertRaises(TypeError, ssl.enum_crls)
606 self.assertRaises(WindowsError, ssl.enum_crls, "")
607
608 crls = ssl.enum_crls("CA")
609 self.assertIsInstance(crls, list)
610 for element in crls:
611 self.assertIsInstance(element, tuple)
612 self.assertEqual(len(element), 2)
613 self.assertIsInstance(element[0], bytes)
614 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
615
616
617 def test_asn1object(self):
618 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
619 '1.3.6.1.5.5.7.3.1')
620
621 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
622 self.assertEqual(val, expected)
623 self.assertEqual(val.nid, 129)
624 self.assertEqual(val.shortname, 'serverAuth')
625 self.assertEqual(val.longname, 'TLS Web Server Authentication')
626 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
627 self.assertIsInstance(val, ssl._ASN1Object)
628 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
629
630 val = ssl._ASN1Object.fromnid(129)
631 self.assertEqual(val, expected)
632 self.assertIsInstance(val, ssl._ASN1Object)
633 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
634 with self.assertRaisesRegexp(ValueError, "unknown NID 100000"):
635 ssl._ASN1Object.fromnid(100000)
636 for i in range(1000):
637 try:
638 obj = ssl._ASN1Object.fromnid(i)
639 except ValueError:
640 pass
641 else:
642 self.assertIsInstance(obj.nid, int)
643 self.assertIsInstance(obj.shortname, str)
644 self.assertIsInstance(obj.longname, str)
645 self.assertIsInstance(obj.oid, (str, type(None)))
646
647 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
648 self.assertEqual(val, expected)
649 self.assertIsInstance(val, ssl._ASN1Object)
650 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
651 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
652 expected)
653 with self.assertRaisesRegexp(ValueError, "unknown object 'serverauth'"):
654 ssl._ASN1Object.fromname('serverauth')
655
656 def test_purpose_enum(self):
657 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
658 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
659 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
660 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
661 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
662 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
663 '1.3.6.1.5.5.7.3.1')
664
665 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
666 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
667 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
668 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
669 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
670 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
671 '1.3.6.1.5.5.7.3.2')
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000672
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100673 def test_unsupported_dtls(self):
674 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
675 self.addCleanup(s.close)
676 with self.assertRaises(NotImplementedError) as cx:
677 ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
678 self.assertEqual(str(cx.exception), "only stream sockets are supported")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500679 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
680 with self.assertRaises(NotImplementedError) as cx:
681 ctx.wrap_socket(s)
682 self.assertEqual(str(cx.exception), "only stream sockets are supported")
683
684 def cert_time_ok(self, timestring, timestamp):
685 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
686
687 def cert_time_fail(self, timestring):
688 with self.assertRaises(ValueError):
689 ssl.cert_time_to_seconds(timestring)
690
691 @unittest.skipUnless(utc_offset(),
692 'local time needs to be different from UTC')
693 def test_cert_time_to_seconds_timezone(self):
694 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
695 # results if local timezone is not UTC
696 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
697 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
698
699 def test_cert_time_to_seconds(self):
700 timestring = "Jan 5 09:34:43 2018 GMT"
701 ts = 1515144883.0
702 self.cert_time_ok(timestring, ts)
703 # accept keyword parameter, assert its name
704 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
705 # accept both %e and %d (space or zero generated by strftime)
706 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
707 # case-insensitive
708 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
709 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
710 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
711 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
712 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
713 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
714 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
715 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
716
717 newyear_ts = 1230768000.0
718 # leap seconds
719 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
720 # same timestamp
721 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
722
723 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
724 # allow 60th second (even if it is not a leap second)
725 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
726 # allow 2nd leap second for compatibility with time.strptime()
727 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
728 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
729
730 # no special treatement for the special value:
731 # 99991231235959Z (rfc 5280)
732 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
733
734 @support.run_with_locale('LC_ALL', '')
735 def test_cert_time_to_seconds_locale(self):
736 # `cert_time_to_seconds()` should be locale independent
737
738 def local_february_name():
739 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
740
741 if local_february_name().lower() == 'feb':
742 self.skipTest("locale-specific month name needs to be "
743 "different from C locale")
744
745 # locale-independent
746 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
747 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
748
749
750class ContextTests(unittest.TestCase):
751
752 @skip_if_broken_ubuntu_ssl
753 def test_constructor(self):
754 for protocol in PROTOCOLS:
755 ssl.SSLContext(protocol)
756 self.assertRaises(TypeError, ssl.SSLContext)
757 self.assertRaises(ValueError, ssl.SSLContext, -1)
758 self.assertRaises(ValueError, ssl.SSLContext, 42)
759
760 @skip_if_broken_ubuntu_ssl
761 def test_protocol(self):
762 for proto in PROTOCOLS:
763 ctx = ssl.SSLContext(proto)
764 self.assertEqual(ctx.protocol, proto)
765
766 def test_ciphers(self):
767 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
768 ctx.set_ciphers("ALL")
769 ctx.set_ciphers("DEFAULT")
770 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
771 ctx.set_ciphers("^$:,;?*'dorothyx")
772
773 @skip_if_broken_ubuntu_ssl
774 def test_options(self):
775 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson10aaca92015-11-11 22:38:41 -0800776 # OP_ALL | OP_NO_SSLv2 | OP_NO_SSLv3 is the default value
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200777 default = (ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
778 if not IS_LIBRESSL and ssl.OPENSSL_VERSION_INFO >= (1, 1, 0):
779 default |= ssl.OP_NO_COMPRESSION
780 self.assertEqual(default, ctx.options)
Benjamin Peterson10aaca92015-11-11 22:38:41 -0800781 ctx.options |= ssl.OP_NO_TLSv1
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200782 self.assertEqual(default | ssl.OP_NO_TLSv1, ctx.options)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500783 if can_clear_options():
Christian Heimesc2fc7c42016-09-05 23:37:13 +0200784 ctx.options = (ctx.options & ~ssl.OP_NO_TLSv1)
785 self.assertEqual(default, ctx.options)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500786 ctx.options = 0
Xiang Zhangc9ba1862017-03-01 15:36:15 +0800787 # Ubuntu has OP_NO_SSLv3 forced on by default
788 self.assertEqual(0, ctx.options & ~ssl.OP_NO_SSLv3)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500789 else:
790 with self.assertRaises(ValueError):
791 ctx.options = 0
792
793 def test_verify_mode(self):
794 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
795 # Default value
796 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
797 ctx.verify_mode = ssl.CERT_OPTIONAL
798 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
799 ctx.verify_mode = ssl.CERT_REQUIRED
800 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
801 ctx.verify_mode = ssl.CERT_NONE
802 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
803 with self.assertRaises(TypeError):
804 ctx.verify_mode = None
805 with self.assertRaises(ValueError):
806 ctx.verify_mode = 42
807
808 @unittest.skipUnless(have_verify_flags(),
809 "verify_flags need OpenSSL > 0.9.8")
810 def test_verify_flags(self):
811 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
Benjamin Peterson72ef9612015-03-04 22:49:41 -0500812 # default value
813 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
814 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT | tf)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500815 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
816 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
817 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
818 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
819 ctx.verify_flags = ssl.VERIFY_DEFAULT
820 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
821 # supports any value
822 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
823 self.assertEqual(ctx.verify_flags,
824 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
825 with self.assertRaises(TypeError):
826 ctx.verify_flags = None
827
828 def test_load_cert_chain(self):
829 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
830 # Combined key and cert in a single file
Benjamin Peterson04439fd2014-11-03 21:05:01 -0500831 ctx.load_cert_chain(CERTFILE, keyfile=None)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500832 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
833 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
834 with self.assertRaises(IOError) as cm:
Martin Panterfd8e8502016-01-30 02:36:00 +0000835 ctx.load_cert_chain(NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500836 self.assertEqual(cm.exception.errno, errno.ENOENT)
837 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
838 ctx.load_cert_chain(BADCERT)
839 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
840 ctx.load_cert_chain(EMPTYCERT)
841 # Separate key and cert
842 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
843 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
844 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
845 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
846 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
847 ctx.load_cert_chain(ONLYCERT)
848 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
849 ctx.load_cert_chain(ONLYKEY)
850 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
851 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
852 # Mismatching key and cert
853 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
854 with self.assertRaisesRegexp(ssl.SSLError, "key values mismatch"):
Martin Panter71202bb2016-01-15 00:25:29 +0000855 ctx.load_cert_chain(CAFILE_CACERT, ONLYKEY)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500856 # Password protected key and cert
857 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
858 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
859 ctx.load_cert_chain(CERTFILE_PROTECTED,
860 password=bytearray(KEY_PASSWORD.encode()))
861 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
862 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
863 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
864 bytearray(KEY_PASSWORD.encode()))
865 with self.assertRaisesRegexp(TypeError, "should be a string"):
866 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
867 with self.assertRaises(ssl.SSLError):
868 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
869 with self.assertRaisesRegexp(ValueError, "cannot be longer"):
870 # openssl has a fixed limit on the password buffer.
871 # PEM_BUFSIZE is generally set to 1kb.
872 # Return a string larger than this.
873 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
874 # Password callback
875 def getpass_unicode():
876 return KEY_PASSWORD
877 def getpass_bytes():
878 return KEY_PASSWORD.encode()
879 def getpass_bytearray():
880 return bytearray(KEY_PASSWORD.encode())
881 def getpass_badpass():
882 return "badpass"
883 def getpass_huge():
884 return b'a' * (1024 * 1024)
885 def getpass_bad_type():
886 return 9
887 def getpass_exception():
888 raise Exception('getpass error')
889 class GetPassCallable:
890 def __call__(self):
891 return KEY_PASSWORD
892 def getpass(self):
893 return KEY_PASSWORD
894 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
895 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
896 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
897 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
898 ctx.load_cert_chain(CERTFILE_PROTECTED,
899 password=GetPassCallable().getpass)
900 with self.assertRaises(ssl.SSLError):
901 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
902 with self.assertRaisesRegexp(ValueError, "cannot be longer"):
903 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
904 with self.assertRaisesRegexp(TypeError, "must return a string"):
905 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
906 with self.assertRaisesRegexp(Exception, "getpass error"):
907 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
908 # Make sure the password function isn't called if it isn't needed
909 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
910
911 def test_load_verify_locations(self):
912 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
913 ctx.load_verify_locations(CERTFILE)
914 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
915 ctx.load_verify_locations(BYTES_CERTFILE)
916 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
Benjamin Peterson876473e2014-08-28 09:33:21 -0400917 ctx.load_verify_locations(cafile=BYTES_CERTFILE.decode('utf-8'))
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500918 self.assertRaises(TypeError, ctx.load_verify_locations)
919 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
920 with self.assertRaises(IOError) as cm:
Martin Panterfd8e8502016-01-30 02:36:00 +0000921 ctx.load_verify_locations(NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500922 self.assertEqual(cm.exception.errno, errno.ENOENT)
Benjamin Peterson876473e2014-08-28 09:33:21 -0400923 with self.assertRaises(IOError):
924 ctx.load_verify_locations(u'')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500925 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
926 ctx.load_verify_locations(BADCERT)
927 ctx.load_verify_locations(CERTFILE, CAPATH)
928 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
929
930 # Issue #10989: crash if the second argument type is invalid
931 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
932
933 def test_load_verify_cadata(self):
934 # test cadata
935 with open(CAFILE_CACERT) as f:
936 cacert_pem = f.read().decode("ascii")
937 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
938 with open(CAFILE_NEURONIO) as f:
939 neuronio_pem = f.read().decode("ascii")
940 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
941
942 # test PEM
943 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
944 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
945 ctx.load_verify_locations(cadata=cacert_pem)
946 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
947 ctx.load_verify_locations(cadata=neuronio_pem)
948 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
949 # cert already in hash table
950 ctx.load_verify_locations(cadata=neuronio_pem)
951 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
952
953 # combined
954 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
955 combined = "\n".join((cacert_pem, neuronio_pem))
956 ctx.load_verify_locations(cadata=combined)
957 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
958
959 # with junk around the certs
960 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
961 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
962 neuronio_pem, "tail"]
963 ctx.load_verify_locations(cadata="\n".join(combined))
964 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
965
966 # test DER
967 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
968 ctx.load_verify_locations(cadata=cacert_der)
969 ctx.load_verify_locations(cadata=neuronio_der)
970 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
971 # cert already in hash table
972 ctx.load_verify_locations(cadata=cacert_der)
973 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
974
975 # combined
976 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
977 combined = b"".join((cacert_der, neuronio_der))
978 ctx.load_verify_locations(cadata=combined)
979 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
980
981 # error cases
982 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
983 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
984
985 with self.assertRaisesRegexp(ssl.SSLError, "no start line"):
986 ctx.load_verify_locations(cadata=u"broken")
987 with self.assertRaisesRegexp(ssl.SSLError, "not enough data"):
988 ctx.load_verify_locations(cadata=b"broken")
989
990
991 def test_load_dh_params(self):
992 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
993 ctx.load_dh_params(DHFILE)
994 if os.name != 'nt':
995 ctx.load_dh_params(BYTES_DHFILE)
996 self.assertRaises(TypeError, ctx.load_dh_params)
997 self.assertRaises(TypeError, ctx.load_dh_params, None)
998 with self.assertRaises(IOError) as cm:
Martin Panterfd8e8502016-01-30 02:36:00 +0000999 ctx.load_dh_params(NONEXISTINGCERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001000 self.assertEqual(cm.exception.errno, errno.ENOENT)
1001 with self.assertRaises(ssl.SSLError) as cm:
1002 ctx.load_dh_params(CERTFILE)
1003
1004 @skip_if_broken_ubuntu_ssl
1005 def test_session_stats(self):
1006 for proto in PROTOCOLS:
1007 ctx = ssl.SSLContext(proto)
1008 self.assertEqual(ctx.session_stats(), {
1009 'number': 0,
1010 'connect': 0,
1011 'connect_good': 0,
1012 'connect_renegotiate': 0,
1013 'accept': 0,
1014 'accept_good': 0,
1015 'accept_renegotiate': 0,
1016 'hits': 0,
1017 'misses': 0,
1018 'timeouts': 0,
1019 'cache_full': 0,
1020 })
1021
1022 def test_set_default_verify_paths(self):
1023 # There's not much we can do to test that it acts as expected,
1024 # so just check it doesn't crash or raise an exception.
1025 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1026 ctx.set_default_verify_paths()
1027
1028 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
1029 def test_set_ecdh_curve(self):
1030 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1031 ctx.set_ecdh_curve("prime256v1")
1032 ctx.set_ecdh_curve(b"prime256v1")
1033 self.assertRaises(TypeError, ctx.set_ecdh_curve)
1034 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
1035 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
1036 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
1037
1038 @needs_sni
1039 def test_sni_callback(self):
1040 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1041
1042 # set_servername_callback expects a callable, or None
1043 self.assertRaises(TypeError, ctx.set_servername_callback)
1044 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
1045 self.assertRaises(TypeError, ctx.set_servername_callback, "")
1046 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
1047
1048 def dummycallback(sock, servername, ctx):
1049 pass
1050 ctx.set_servername_callback(None)
1051 ctx.set_servername_callback(dummycallback)
1052
1053 @needs_sni
1054 def test_sni_callback_refcycle(self):
1055 # Reference cycles through the servername callback are detected
1056 # and cleared.
1057 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1058 def dummycallback(sock, servername, ctx, cycle=ctx):
1059 pass
1060 ctx.set_servername_callback(dummycallback)
1061 wr = weakref.ref(ctx)
1062 del ctx, dummycallback
1063 gc.collect()
1064 self.assertIs(wr(), None)
1065
1066 def test_cert_store_stats(self):
1067 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1068 self.assertEqual(ctx.cert_store_stats(),
1069 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1070 ctx.load_cert_chain(CERTFILE)
1071 self.assertEqual(ctx.cert_store_stats(),
1072 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1073 ctx.load_verify_locations(CERTFILE)
1074 self.assertEqual(ctx.cert_store_stats(),
1075 {'x509_ca': 0, 'crl': 0, 'x509': 1})
Martin Panter71202bb2016-01-15 00:25:29 +00001076 ctx.load_verify_locations(CAFILE_CACERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001077 self.assertEqual(ctx.cert_store_stats(),
1078 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1079
1080 def test_get_ca_certs(self):
1081 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1082 self.assertEqual(ctx.get_ca_certs(), [])
1083 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1084 ctx.load_verify_locations(CERTFILE)
1085 self.assertEqual(ctx.get_ca_certs(), [])
Martin Panter71202bb2016-01-15 00:25:29 +00001086 # but CAFILE_CACERT is a CA cert
1087 ctx.load_verify_locations(CAFILE_CACERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001088 self.assertEqual(ctx.get_ca_certs(),
1089 [{'issuer': ((('organizationName', 'Root CA'),),
1090 (('organizationalUnitName', 'http://www.cacert.org'),),
1091 (('commonName', 'CA Cert Signing Authority'),),
1092 (('emailAddress', 'support@cacert.org'),)),
1093 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1094 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1095 'serialNumber': '00',
1096 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
1097 'subject': ((('organizationName', 'Root CA'),),
1098 (('organizationalUnitName', 'http://www.cacert.org'),),
1099 (('commonName', 'CA Cert Signing Authority'),),
1100 (('emailAddress', 'support@cacert.org'),)),
1101 'version': 3}])
1102
Martin Panter71202bb2016-01-15 00:25:29 +00001103 with open(CAFILE_CACERT) as f:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001104 pem = f.read()
1105 der = ssl.PEM_cert_to_DER_cert(pem)
1106 self.assertEqual(ctx.get_ca_certs(True), [der])
1107
1108 def test_load_default_certs(self):
1109 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1110 ctx.load_default_certs()
1111
1112 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1113 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1114 ctx.load_default_certs()
1115
1116 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1117 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1118
1119 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1120 self.assertRaises(TypeError, ctx.load_default_certs, None)
1121 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1122
Benjamin Petersona02ae252014-10-03 18:17:15 -04001123 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Christian Heimesc2fc7c42016-09-05 23:37:13 +02001124 @unittest.skipIf(IS_LIBRESSL, "LibreSSL doesn't support env vars")
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -04001125 def test_load_default_certs_env(self):
1126 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1127 with support.EnvironmentVarGuard() as env:
1128 env["SSL_CERT_DIR"] = CAPATH
1129 env["SSL_CERT_FILE"] = CERTFILE
1130 ctx.load_default_certs()
1131 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1132
Benjamin Petersona02ae252014-10-03 18:17:15 -04001133 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
1134 def test_load_default_certs_env_windows(self):
1135 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1136 ctx.load_default_certs()
1137 stats = ctx.cert_store_stats()
1138
1139 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1140 with support.EnvironmentVarGuard() as env:
1141 env["SSL_CERT_DIR"] = CAPATH
1142 env["SSL_CERT_FILE"] = CERTFILE
1143 ctx.load_default_certs()
1144 stats["x509"] += 1
1145 self.assertEqual(ctx.cert_store_stats(), stats)
1146
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001147 def test_create_default_context(self):
1148 ctx = ssl.create_default_context()
1149 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1150 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1151 self.assertTrue(ctx.check_hostname)
1152 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1153 self.assertEqual(
1154 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1155 getattr(ssl, "OP_NO_COMPRESSION", 0),
1156 )
1157
1158 with open(SIGNING_CA) as f:
1159 cadata = f.read().decode("ascii")
1160 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1161 cadata=cadata)
1162 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1163 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1164 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1165 self.assertEqual(
1166 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1167 getattr(ssl, "OP_NO_COMPRESSION", 0),
1168 )
1169
1170 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
1171 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1172 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1173 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1174 self.assertEqual(
1175 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1176 getattr(ssl, "OP_NO_COMPRESSION", 0),
1177 )
1178 self.assertEqual(
1179 ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0),
1180 getattr(ssl, "OP_SINGLE_DH_USE", 0),
1181 )
1182 self.assertEqual(
1183 ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1184 getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1185 )
1186
1187 def test__create_stdlib_context(self):
1188 ctx = ssl._create_stdlib_context()
1189 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1190 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1191 self.assertFalse(ctx.check_hostname)
1192 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1193
1194 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1195 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1196 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1197 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1198
1199 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
1200 cert_reqs=ssl.CERT_REQUIRED,
1201 check_hostname=True)
1202 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1203 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1204 self.assertTrue(ctx.check_hostname)
1205 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1206
1207 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1208 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1209 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1210 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1211
Nick Coghlandbcd4572016-03-20 22:39:15 +10001212 def test__https_verify_certificates(self):
1213 # Unit test to check the contect factory mapping
1214 # The factories themselves are tested above
1215 # This test will fail by design if run under PYTHONHTTPSVERIFY=0
1216 # (as will various test_httplib tests)
1217
1218 # Uses a fresh SSL module to avoid affecting the real one
1219 local_ssl = support.import_fresh_module("ssl")
1220 # Certificate verification is enabled by default
1221 self.assertIs(local_ssl._create_default_https_context,
1222 local_ssl.create_default_context)
1223 # Turn default verification off
1224 local_ssl._https_verify_certificates(enable=False)
1225 self.assertIs(local_ssl._create_default_https_context,
1226 local_ssl._create_unverified_context)
1227 # And back on
1228 local_ssl._https_verify_certificates(enable=True)
1229 self.assertIs(local_ssl._create_default_https_context,
1230 local_ssl.create_default_context)
1231 # The default behaviour is to enable
1232 local_ssl._https_verify_certificates(enable=False)
1233 local_ssl._https_verify_certificates()
1234 self.assertIs(local_ssl._create_default_https_context,
1235 local_ssl.create_default_context)
1236
1237 def test__https_verify_envvar(self):
1238 # Unit test to check the PYTHONHTTPSVERIFY handling
1239 # Need to use a subprocess so it can still be run under -E
1240 https_is_verified = """import ssl, sys; \
1241 status = "Error: _create_default_https_context does not verify certs" \
1242 if ssl._create_default_https_context is \
1243 ssl._create_unverified_context \
1244 else None; \
1245 sys.exit(status)"""
1246 https_is_not_verified = """import ssl, sys; \
1247 status = "Error: _create_default_https_context verifies certs" \
1248 if ssl._create_default_https_context is \
1249 ssl.create_default_context \
1250 else None; \
1251 sys.exit(status)"""
1252 extra_env = {}
1253 # Omitting it leaves verification on
1254 assert_python_ok("-c", https_is_verified, **extra_env)
1255 # Setting it to zero turns verification off
1256 extra_env[ssl._https_verify_envvar] = "0"
1257 assert_python_ok("-c", https_is_not_verified, **extra_env)
1258 # Any other value should also leave it on
1259 for setting in ("", "1", "enabled", "foo"):
1260 extra_env[ssl._https_verify_envvar] = setting
1261 assert_python_ok("-c", https_is_verified, **extra_env)
1262
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001263 def test_check_hostname(self):
1264 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1265 self.assertFalse(ctx.check_hostname)
1266
1267 # Requires CERT_REQUIRED or CERT_OPTIONAL
1268 with self.assertRaises(ValueError):
1269 ctx.check_hostname = True
1270 ctx.verify_mode = ssl.CERT_REQUIRED
1271 self.assertFalse(ctx.check_hostname)
1272 ctx.check_hostname = True
1273 self.assertTrue(ctx.check_hostname)
1274
1275 ctx.verify_mode = ssl.CERT_OPTIONAL
1276 ctx.check_hostname = True
1277 self.assertTrue(ctx.check_hostname)
1278
1279 # Cannot set CERT_NONE with check_hostname enabled
1280 with self.assertRaises(ValueError):
1281 ctx.verify_mode = ssl.CERT_NONE
1282 ctx.check_hostname = False
1283 self.assertFalse(ctx.check_hostname)
1284
1285
1286class SSLErrorTests(unittest.TestCase):
1287
1288 def test_str(self):
1289 # The str() of a SSLError doesn't include the errno
1290 e = ssl.SSLError(1, "foo")
1291 self.assertEqual(str(e), "foo")
1292 self.assertEqual(e.errno, 1)
1293 # Same for a subclass
1294 e = ssl.SSLZeroReturnError(1, "foo")
1295 self.assertEqual(str(e), "foo")
1296 self.assertEqual(e.errno, 1)
1297
1298 def test_lib_reason(self):
1299 # Test the library and reason attributes
1300 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1301 with self.assertRaises(ssl.SSLError) as cm:
1302 ctx.load_dh_params(CERTFILE)
1303 self.assertEqual(cm.exception.library, 'PEM')
1304 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1305 s = str(cm.exception)
1306 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1307
1308 def test_subclass(self):
1309 # Check that the appropriate SSLError subclass is raised
1310 # (this only tests one of them)
1311 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1312 with closing(socket.socket()) as s:
1313 s.bind(("127.0.0.1", 0))
1314 s.listen(5)
1315 c = socket.socket()
1316 c.connect(s.getsockname())
1317 c.setblocking(False)
1318 with closing(ctx.wrap_socket(c, False, do_handshake_on_connect=False)) as c:
1319 with self.assertRaises(ssl.SSLWantReadError) as cm:
1320 c.do_handshake()
1321 s = str(cm.exception)
1322 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1323 # For compatibility
1324 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
Antoine Pitrou63cc99d2013-12-28 17:26:33 +01001325
Antoine Pitrouf9de5342010-04-05 21:35:07 +00001326
Bill Janssen934b16d2008-06-28 22:19:33 +00001327class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +00001328
Antoine Pitrou3945c862010-04-28 21:11:01 +00001329 def test_connect(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001330 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001331 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1332 cert_reqs=ssl.CERT_NONE)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001333 try:
Martin Panter71202bb2016-01-15 00:25:29 +00001334 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001335 self.assertEqual({}, s.getpeercert())
1336 finally:
1337 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +00001338
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001339 # this should fail because we have no verification certs
1340 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1341 cert_reqs=ssl.CERT_REQUIRED)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001342 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
Martin Panter71202bb2016-01-15 00:25:29 +00001343 s.connect, (REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001344 s.close()
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001345
1346 # this should succeed because we specify the root cert
1347 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1348 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter71202bb2016-01-15 00:25:29 +00001349 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001350 try:
Martin Panter71202bb2016-01-15 00:25:29 +00001351 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001352 self.assertTrue(s.getpeercert())
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001353 finally:
1354 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +00001355
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001356 def test_connect_ex(self):
1357 # Issue #11326: check connect_ex() implementation
Martin Panter71202bb2016-01-15 00:25:29 +00001358 with support.transient_internet(REMOTE_HOST):
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001359 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1360 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter71202bb2016-01-15 00:25:29 +00001361 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001362 try:
Martin Panter71202bb2016-01-15 00:25:29 +00001363 self.assertEqual(0, s.connect_ex((REMOTE_HOST, 443)))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001364 self.assertTrue(s.getpeercert())
1365 finally:
1366 s.close()
1367
1368 def test_non_blocking_connect_ex(self):
1369 # Issue #11326: non-blocking connect_ex() should allow handshake
1370 # to proceed after the socket gets ready.
Martin Panter71202bb2016-01-15 00:25:29 +00001371 with support.transient_internet(REMOTE_HOST):
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001372 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1373 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter71202bb2016-01-15 00:25:29 +00001374 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001375 do_handshake_on_connect=False)
1376 try:
1377 s.setblocking(False)
Martin Panter71202bb2016-01-15 00:25:29 +00001378 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +00001379 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1380 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001381 # Wait for connect to finish
1382 select.select([], [s], [], 5.0)
1383 # Non-blocking handshake
1384 while True:
1385 try:
1386 s.do_handshake()
1387 break
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001388 except ssl.SSLWantReadError:
1389 select.select([s], [], [], 5.0)
1390 except ssl.SSLWantWriteError:
1391 select.select([], [s], [], 5.0)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001392 # SSL established
1393 self.assertTrue(s.getpeercert())
1394 finally:
1395 s.close()
1396
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001397 def test_timeout_connect_ex(self):
1398 # Issue #12065: on a timeout, connect_ex() should return the original
1399 # errno (mimicking the behaviour of non-SSL sockets).
Martin Panter71202bb2016-01-15 00:25:29 +00001400 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001401 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1402 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter71202bb2016-01-15 00:25:29 +00001403 ca_certs=REMOTE_ROOT_CERT,
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001404 do_handshake_on_connect=False)
1405 try:
1406 s.settimeout(0.0000001)
Martin Panter71202bb2016-01-15 00:25:29 +00001407 rc = s.connect_ex((REMOTE_HOST, 443))
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001408 if rc == 0:
Martin Panter71202bb2016-01-15 00:25:29 +00001409 self.skipTest("REMOTE_HOST responded too quickly")
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001410 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1411 finally:
1412 s.close()
1413
1414 def test_connect_ex_error(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001415 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001416 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1417 cert_reqs=ssl.CERT_REQUIRED,
Martin Panter71202bb2016-01-15 00:25:29 +00001418 ca_certs=REMOTE_ROOT_CERT)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001419 try:
Martin Panter71202bb2016-01-15 00:25:29 +00001420 rc = s.connect_ex((REMOTE_HOST, 444))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001421 # Issue #19919: Windows machines or VMs hosted on Windows
1422 # machines sometimes return EWOULDBLOCK.
Martin Panter71202bb2016-01-15 00:25:29 +00001423 errors = (
1424 errno.ECONNREFUSED, errno.EHOSTUNREACH, errno.ETIMEDOUT,
1425 errno.EWOULDBLOCK,
1426 )
1427 self.assertIn(rc, errors)
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001428 finally:
1429 s.close()
1430
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001431 def test_connect_with_context(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001432 with support.transient_internet(REMOTE_HOST):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001433 # Same as test_connect, but with a separately created context
1434 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1435 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001436 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001437 try:
1438 self.assertEqual({}, s.getpeercert())
1439 finally:
1440 s.close()
1441 # Same with a server hostname
1442 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
Martin Panter71202bb2016-01-15 00:25:29 +00001443 server_hostname=REMOTE_HOST)
1444 s.connect((REMOTE_HOST, 443))
Benjamin Peterson31aa69e2014-11-23 20:13:31 -06001445 s.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001446 # This should fail because we have no verification certs
1447 ctx.verify_mode = ssl.CERT_REQUIRED
1448 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1449 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
Martin Panter71202bb2016-01-15 00:25:29 +00001450 s.connect, (REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001451 s.close()
1452 # This should succeed because we specify the root cert
Martin Panter71202bb2016-01-15 00:25:29 +00001453 ctx.load_verify_locations(REMOTE_ROOT_CERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001454 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001455 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001456 try:
1457 cert = s.getpeercert()
1458 self.assertTrue(cert)
1459 finally:
1460 s.close()
1461
1462 def test_connect_capath(self):
1463 # Verify server certificates using the `capath` argument
1464 # NOTE: the subject hashing algorithm has been changed between
1465 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1466 # contain both versions of each certificate (same content, different
1467 # filename) for this test to be portable across OpenSSL releases.
Martin Panter71202bb2016-01-15 00:25:29 +00001468 with support.transient_internet(REMOTE_HOST):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001469 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1470 ctx.verify_mode = ssl.CERT_REQUIRED
1471 ctx.load_verify_locations(capath=CAPATH)
1472 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001473 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001474 try:
1475 cert = s.getpeercert()
1476 self.assertTrue(cert)
1477 finally:
1478 s.close()
1479 # Same with a bytes `capath` argument
1480 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1481 ctx.verify_mode = ssl.CERT_REQUIRED
1482 ctx.load_verify_locations(capath=BYTES_CAPATH)
1483 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001484 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001485 try:
1486 cert = s.getpeercert()
1487 self.assertTrue(cert)
1488 finally:
1489 s.close()
1490
1491 def test_connect_cadata(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001492 with open(REMOTE_ROOT_CERT) as f:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001493 pem = f.read().decode('ascii')
1494 der = ssl.PEM_cert_to_DER_cert(pem)
Martin Panter71202bb2016-01-15 00:25:29 +00001495 with support.transient_internet(REMOTE_HOST):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001496 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1497 ctx.verify_mode = ssl.CERT_REQUIRED
1498 ctx.load_verify_locations(cadata=pem)
1499 with closing(ctx.wrap_socket(socket.socket(socket.AF_INET))) as s:
Martin Panter71202bb2016-01-15 00:25:29 +00001500 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001501 cert = s.getpeercert()
1502 self.assertTrue(cert)
1503
1504 # same with DER
1505 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1506 ctx.verify_mode = ssl.CERT_REQUIRED
1507 ctx.load_verify_locations(cadata=der)
1508 with closing(ctx.wrap_socket(socket.socket(socket.AF_INET))) as s:
Martin Panter71202bb2016-01-15 00:25:29 +00001509 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001510 cert = s.getpeercert()
1511 self.assertTrue(cert)
1512
Antoine Pitrou55841ac2010-04-24 10:43:57 +00001513 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1514 def test_makefile_close(self):
1515 # Issue #5238: creating a file-like object with makefile() shouldn't
1516 # delay closing the underlying "real socket" (here tested with its
1517 # file descriptor, hence skipping the test under Windows).
Martin Panter71202bb2016-01-15 00:25:29 +00001518 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001519 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001520 ss.connect((REMOTE_HOST, 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001521 fd = ss.fileno()
1522 f = ss.makefile()
1523 f.close()
1524 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +00001525 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001526 # Closing the SSL socket should close the fd too
1527 ss.close()
1528 gc.collect()
1529 with self.assertRaises(OSError) as e:
1530 os.read(fd, 0)
1531 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +00001532
Antoine Pitrou3945c862010-04-28 21:11:01 +00001533 def test_non_blocking_handshake(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001534 with support.transient_internet(REMOTE_HOST):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001535 s = socket.socket(socket.AF_INET)
Martin Panter71202bb2016-01-15 00:25:29 +00001536 s.connect((REMOTE_HOST, 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001537 s.setblocking(False)
1538 s = ssl.wrap_socket(s,
1539 cert_reqs=ssl.CERT_NONE,
1540 do_handshake_on_connect=False)
1541 count = 0
1542 while True:
1543 try:
1544 count += 1
1545 s.do_handshake()
1546 break
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001547 except ssl.SSLWantReadError:
1548 select.select([s], [], [])
1549 except ssl.SSLWantWriteError:
1550 select.select([], [s], [])
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001551 s.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001552 if support.verbose:
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001553 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +00001554
Antoine Pitrou3945c862010-04-28 21:11:01 +00001555 def test_get_server_certificate(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001556 def _test_get_server_certificate(host, port, cert=None):
1557 with support.transient_internet(host):
1558 pem = ssl.get_server_certificate((host, port))
1559 if not pem:
1560 self.fail("No server certificate on %s:%s!" % (host, port))
Bill Janssen296a59d2007-09-16 22:06:00 +00001561
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001562 try:
1563 pem = ssl.get_server_certificate((host, port),
1564 ca_certs=CERTFILE)
1565 except ssl.SSLError as x:
1566 #should fail
1567 if support.verbose:
1568 sys.stdout.write("%s\n" % x)
1569 else:
1570 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001571 pem = ssl.get_server_certificate((host, port),
1572 ca_certs=cert)
1573 if not pem:
1574 self.fail("No server certificate on %s:%s!" % (host, port))
1575 if support.verbose:
1576 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
1577
Martin Panter71202bb2016-01-15 00:25:29 +00001578 _test_get_server_certificate(REMOTE_HOST, 443, REMOTE_ROOT_CERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001579 if support.IPV6_ENABLED:
1580 _test_get_server_certificate('ipv6.google.com', 443)
1581
1582 def test_ciphers(self):
Martin Panter71202bb2016-01-15 00:25:29 +00001583 remote = (REMOTE_HOST, 443)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001584 with support.transient_internet(remote[0]):
1585 with closing(ssl.wrap_socket(socket.socket(socket.AF_INET),
1586 cert_reqs=ssl.CERT_NONE, ciphers="ALL")) as s:
1587 s.connect(remote)
1588 with closing(ssl.wrap_socket(socket.socket(socket.AF_INET),
1589 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")) as s:
1590 s.connect(remote)
1591 # Error checking can happen at instantiation or when connecting
1592 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
1593 with closing(socket.socket(socket.AF_INET)) as sock:
1594 s = ssl.wrap_socket(sock,
1595 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1596 s.connect(remote)
Bill Janssen296a59d2007-09-16 22:06:00 +00001597
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001598 def test_get_ca_certs_capath(self):
1599 # capath certs are loaded on request
Martin Panter71202bb2016-01-15 00:25:29 +00001600 with support.transient_internet(REMOTE_HOST):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001601 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1602 ctx.verify_mode = ssl.CERT_REQUIRED
1603 ctx.load_verify_locations(capath=CAPATH)
1604 self.assertEqual(ctx.get_ca_certs(), [])
1605 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
Martin Panter71202bb2016-01-15 00:25:29 +00001606 s.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001607 try:
1608 cert = s.getpeercert()
1609 self.assertTrue(cert)
1610 finally:
1611 s.close()
1612 self.assertEqual(len(ctx.get_ca_certs()), 1)
1613
1614 @needs_sni
1615 def test_context_setget(self):
1616 # Check that the context of a connected socket can be replaced.
Martin Panter71202bb2016-01-15 00:25:29 +00001617 with support.transient_internet(REMOTE_HOST):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001618 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1619 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1620 s = socket.socket(socket.AF_INET)
1621 with closing(ctx1.wrap_socket(s)) as ss:
Martin Panter71202bb2016-01-15 00:25:29 +00001622 ss.connect((REMOTE_HOST, 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001623 self.assertIs(ss.context, ctx1)
1624 self.assertIs(ss._sslobj.context, ctx1)
1625 ss.context = ctx2
1626 self.assertIs(ss.context, ctx2)
1627 self.assertIs(ss._sslobj.context, ctx2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001628
Bill Janssen98d19da2007-09-10 21:51:02 +00001629try:
1630 import threading
1631except ImportError:
1632 _have_threads = False
1633else:
Bill Janssen98d19da2007-09-10 21:51:02 +00001634 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001635
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001636 from test.ssl_servers import make_https_server
1637
Bill Janssen98d19da2007-09-10 21:51:02 +00001638 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001639
Bill Janssen98d19da2007-09-10 21:51:02 +00001640 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001641
Bill Janssen98d19da2007-09-10 21:51:02 +00001642 """A mildly complicated class, because we want it to work both
1643 with and without the SSL wrapper around the socket connection, so
1644 that we can test the STARTTLS functionality."""
1645
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001646 def __init__(self, server, connsock, addr):
Bill Janssen98d19da2007-09-10 21:51:02 +00001647 self.server = server
1648 self.running = False
1649 self.sock = connsock
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001650 self.addr = addr
Bill Janssen98d19da2007-09-10 21:51:02 +00001651 self.sock.setblocking(1)
1652 self.sslconn = None
1653 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001654 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +00001655
Antoine Pitrou3945c862010-04-28 21:11:01 +00001656 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001657 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001658 self.sslconn = self.server.context.wrap_socket(
1659 self.sock, server_side=True)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05001660 self.server.selected_npn_protocols.append(self.sslconn.selected_npn_protocol())
1661 self.server.selected_alpn_protocols.append(self.sslconn.selected_alpn_protocol())
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001662 except socket.error as e:
1663 # We treat ConnectionResetError as though it were an
1664 # SSLError - OpenSSL on Ubuntu abruptly closes the
1665 # connection when asked to use an unsupported protocol.
1666 #
Antoine Pitroudb187842010-04-27 10:32:58 +00001667 # XXX Various errors can have happened here, for example
1668 # a mismatching protocol version, an invalid certificate,
1669 # or a low-level bug. This should be made more discriminating.
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001670 if not isinstance(e, ssl.SSLError) and e.errno != errno.ECONNRESET:
1671 raise
Antoine Pitroud76088d2012-01-03 22:46:48 +01001672 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +00001673 if self.server.chatty:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001674 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitroudb187842010-04-27 10:32:58 +00001675 self.running = False
1676 self.server.stop()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001677 self.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001678 return False
Bill Janssen98d19da2007-09-10 21:51:02 +00001679 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001680 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
1681 cert = self.sslconn.getpeercert()
1682 if support.verbose and self.server.chatty:
1683 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1684 cert_binary = self.sslconn.getpeercert(True)
1685 if support.verbose and self.server.chatty:
1686 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1687 cipher = self.sslconn.cipher()
1688 if support.verbose and self.server.chatty:
1689 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
1690 sys.stdout.write(" server: selected protocol is now "
1691 + str(self.sslconn.selected_npn_protocol()) + "\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001692 return True
1693
1694 def read(self):
1695 if self.sslconn:
1696 return self.sslconn.read()
1697 else:
1698 return self.sock.recv(1024)
1699
1700 def write(self, bytes):
1701 if self.sslconn:
1702 return self.sslconn.write(bytes)
1703 else:
1704 return self.sock.send(bytes)
1705
1706 def close(self):
1707 if self.sslconn:
1708 self.sslconn.close()
1709 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001710 self.sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001711
Antoine Pitrou3945c862010-04-28 21:11:01 +00001712 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001713 self.running = True
1714 if not self.server.starttls_server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001715 if not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +00001716 return
1717 while self.running:
1718 try:
1719 msg = self.read()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001720 stripped = msg.strip()
1721 if not stripped:
Bill Janssen98d19da2007-09-10 21:51:02 +00001722 # eof, so quit this handler
1723 self.running = False
1724 self.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001725 elif stripped == b'over':
1726 if support.verbose and self.server.connectionchatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001727 sys.stdout.write(" server: client closed connection\n")
1728 self.close()
1729 return
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001730 elif (self.server.starttls_server and
1731 stripped == b'STARTTLS'):
1732 if support.verbose and self.server.connectionchatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001733 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001734 self.write(b"OK\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001735 if not self.wrap_conn():
1736 return
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001737 elif (self.server.starttls_server and self.sslconn
1738 and stripped == b'ENDTLS'):
1739 if support.verbose and self.server.connectionchatty:
Bill Janssen39295c22008-08-12 16:31:21 +00001740 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001741 self.write(b"OK\n")
1742 self.sock = self.sslconn.unwrap()
Bill Janssen39295c22008-08-12 16:31:21 +00001743 self.sslconn = None
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001744 if support.verbose and self.server.connectionchatty:
Bill Janssen39295c22008-08-12 16:31:21 +00001745 sys.stdout.write(" server: connection is now unencrypted...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001746 elif stripped == b'CB tls-unique':
1747 if support.verbose and self.server.connectionchatty:
1748 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1749 data = self.sslconn.get_channel_binding("tls-unique")
1750 self.write(repr(data).encode("us-ascii") + b"\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001751 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001752 if (support.verbose and
Bill Janssen98d19da2007-09-10 21:51:02 +00001753 self.server.connectionchatty):
1754 ctype = (self.sslconn and "encrypted") or "unencrypted"
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001755 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1756 % (msg, ctype, msg.lower(), ctype))
Bill Janssen98d19da2007-09-10 21:51:02 +00001757 self.write(msg.lower())
1758 except ssl.SSLError:
1759 if self.server.chatty:
1760 handle_error("Test server failure:\n")
1761 self.close()
1762 self.running = False
1763 # normally, we'd just stop here, but for the test
1764 # harness, we want to stop the server
1765 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +00001766
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001767 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +00001768 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +00001769 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05001770 npn_protocols=None, alpn_protocols=None,
1771 ciphers=None, context=None):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001772 if context:
1773 self.context = context
1774 else:
1775 self.context = ssl.SSLContext(ssl_version
1776 if ssl_version is not None
1777 else ssl.PROTOCOL_TLSv1)
1778 self.context.verify_mode = (certreqs if certreqs is not None
1779 else ssl.CERT_NONE)
1780 if cacerts:
1781 self.context.load_verify_locations(cacerts)
1782 if certificate:
1783 self.context.load_cert_chain(certificate)
1784 if npn_protocols:
1785 self.context.set_npn_protocols(npn_protocols)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05001786 if alpn_protocols:
1787 self.context.set_alpn_protocols(alpn_protocols)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001788 if ciphers:
1789 self.context.set_ciphers(ciphers)
Bill Janssen98d19da2007-09-10 21:51:02 +00001790 self.chatty = chatty
1791 self.connectionchatty = connectionchatty
1792 self.starttls_server = starttls_server
1793 self.sock = socket.socket()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001794 self.port = support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +00001795 self.flag = None
Bill Janssen98d19da2007-09-10 21:51:02 +00001796 self.active = False
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05001797 self.selected_npn_protocols = []
1798 self.selected_alpn_protocols = []
Antoine Pitroud76088d2012-01-03 22:46:48 +01001799 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001800 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001801 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +00001802
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001803 def __enter__(self):
1804 self.start(threading.Event())
1805 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +01001806 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001807
1808 def __exit__(self, *args):
1809 self.stop()
1810 self.join()
1811
Antoine Pitrou3945c862010-04-28 21:11:01 +00001812 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +00001813 self.flag = flag
1814 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001815
Antoine Pitrou3945c862010-04-28 21:11:01 +00001816 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +00001817 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +00001818 self.sock.listen(5)
1819 self.active = True
1820 if self.flag:
1821 # signal an event
1822 self.flag.set()
1823 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001824 try:
Bill Janssen98d19da2007-09-10 21:51:02 +00001825 newconn, connaddr = self.sock.accept()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001826 if support.verbose and self.chatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001827 sys.stdout.write(' server: new connection from '
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001828 + repr(connaddr) + '\n')
1829 handler = self.ConnectionHandler(self, newconn, connaddr)
Bill Janssen98d19da2007-09-10 21:51:02 +00001830 handler.start()
Antoine Pitrou7a556842012-01-27 17:33:01 +01001831 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +00001832 except socket.timeout:
1833 pass
1834 except KeyboardInterrupt:
1835 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +00001836 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001837
Antoine Pitrou3945c862010-04-28 21:11:01 +00001838 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001839 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001840
Bill Janssen934b16d2008-06-28 22:19:33 +00001841 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +00001842
Antoine Pitrou3945c862010-04-28 21:11:01 +00001843 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +00001844
Antoine Pitrou3945c862010-04-28 21:11:01 +00001845 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +00001846
1847 def __init__(self, conn, certfile):
Bill Janssen934b16d2008-06-28 22:19:33 +00001848 self.socket = ssl.wrap_socket(conn, server_side=True,
1849 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +00001850 do_handshake_on_connect=False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001851 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroufc69af12010-04-24 20:04:58 +00001852 self._ssl_accepting = True
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001853 self._do_ssl_handshake()
Bill Janssen934b16d2008-06-28 22:19:33 +00001854
1855 def readable(self):
1856 if isinstance(self.socket, ssl.SSLSocket):
1857 while self.socket.pending() > 0:
1858 self.handle_read_event()
1859 return True
1860
Antoine Pitroufc69af12010-04-24 20:04:58 +00001861 def _do_ssl_handshake(self):
1862 try:
1863 self.socket.do_handshake()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001864 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1865 return
1866 except ssl.SSLEOFError:
1867 return self.handle_close()
1868 except ssl.SSLError:
Antoine Pitroufc69af12010-04-24 20:04:58 +00001869 raise
1870 except socket.error, err:
1871 if err.args[0] == errno.ECONNABORTED:
1872 return self.handle_close()
1873 else:
1874 self._ssl_accepting = False
1875
Bill Janssen934b16d2008-06-28 22:19:33 +00001876 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +00001877 if self._ssl_accepting:
1878 self._do_ssl_handshake()
1879 else:
1880 data = self.recv(1024)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001881 if support.verbose:
1882 sys.stdout.write(" server: read %s from client\n" % repr(data))
1883 if not data:
1884 self.close()
1885 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001886 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +00001887
1888 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +00001889 self.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001890 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00001891 sys.stdout.write(" server: closed connection %s\n" % self.socket)
1892
1893 def handle_error(self):
1894 raise
1895
1896 def __init__(self, certfile):
1897 self.certfile = certfile
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001898 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1899 self.port = support.bind_port(sock, '')
1900 asyncore.dispatcher.__init__(self, sock)
Bill Janssen934b16d2008-06-28 22:19:33 +00001901 self.listen(5)
1902
1903 def handle_accept(self):
1904 sock_obj, addr = self.accept()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001905 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00001906 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
1907 self.ConnectionHandler(sock_obj, self.certfile)
1908
1909 def handle_error(self):
1910 raise
1911
1912 def __init__(self, certfile):
1913 self.flag = None
1914 self.active = False
1915 self.server = self.EchoServer(certfile)
1916 self.port = self.server.port
1917 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001918 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +00001919
1920 def __str__(self):
1921 return "<%s %s>" % (self.__class__.__name__, self.server)
1922
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001923 def __enter__(self):
1924 self.start(threading.Event())
1925 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +01001926 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001927
1928 def __exit__(self, *args):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001929 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001930 sys.stdout.write(" cleanup: stopping server.\n")
1931 self.stop()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001932 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001933 sys.stdout.write(" cleanup: joining server thread.\n")
1934 self.join()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001935 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001936 sys.stdout.write(" cleanup: successfully joined.\n")
Victor Stinnerd1c862f2017-05-03 03:47:34 +02001937 # make sure that ConnectionHandler is removed from socket_map
1938 asyncore.close_all(ignore_all=True)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001939
Antoine Pitrou3945c862010-04-28 21:11:01 +00001940 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +00001941 self.flag = flag
1942 threading.Thread.start(self)
1943
Antoine Pitrou3945c862010-04-28 21:11:01 +00001944 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +00001945 self.active = True
1946 if self.flag:
1947 self.flag.set()
1948 while self.active:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001949 try:
1950 asyncore.loop(1)
1951 except:
1952 pass
Bill Janssen934b16d2008-06-28 22:19:33 +00001953
Antoine Pitrou3945c862010-04-28 21:11:01 +00001954 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +00001955 self.active = False
1956 self.server.close()
1957
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001958 def server_params_test(client_context, server_context, indata=b"FOO\n",
1959 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001960 """
1961 Launch a server, connect a client to it and try various reads
1962 and writes.
1963 """
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001964 stats = {}
1965 server = ThreadedEchoServer(context=server_context,
Bill Janssen98d19da2007-09-10 21:51:02 +00001966 chatty=chatty,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001967 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001968 with server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001969 with closing(client_context.wrap_socket(socket.socket(),
1970 server_hostname=sni_name)) as s:
1971 s.connect((HOST, server.port))
1972 for arg in [indata, bytearray(indata), memoryview(indata)]:
1973 if connectionchatty:
1974 if support.verbose:
1975 sys.stdout.write(
1976 " client: sending %r...\n" % indata)
1977 s.write(arg)
1978 outdata = s.read()
1979 if connectionchatty:
1980 if support.verbose:
1981 sys.stdout.write(" client: read %r\n" % outdata)
1982 if outdata != indata.lower():
1983 raise AssertionError(
1984 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1985 % (outdata[:20], len(outdata),
1986 indata[:20].lower(), len(indata)))
1987 s.write(b"over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001988 if connectionchatty:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001989 if support.verbose:
1990 sys.stdout.write(" client: closing connection.\n")
1991 stats.update({
1992 'compression': s.compression(),
1993 'cipher': s.cipher(),
1994 'peercert': s.getpeercert(),
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05001995 'client_alpn_protocol': s.selected_alpn_protocol(),
Alex Gaynore98205d2014-09-04 13:33:22 -07001996 'client_npn_protocol': s.selected_npn_protocol(),
1997 'version': s.version(),
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001998 })
1999 s.close()
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002000 stats['server_alpn_protocols'] = server.selected_alpn_protocols
2001 stats['server_npn_protocols'] = server.selected_npn_protocols
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002002 return stats
Bill Janssen98d19da2007-09-10 21:51:02 +00002003
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002004 def try_protocol_combo(server_protocol, client_protocol, expect_success,
2005 certsreqs=None, server_options=0, client_options=0):
Alex Gaynore98205d2014-09-04 13:33:22 -07002006 """
2007 Try to SSL-connect using *client_protocol* to *server_protocol*.
2008 If *expect_success* is true, assert that the connection succeeds,
2009 if it's false, assert that the connection fails.
2010 Also, if *expect_success* is a string, assert that it is the protocol
2011 version actually used by the connection.
2012 """
Benjamin Peterson5b63acd2008-03-29 15:24:25 +00002013 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +00002014 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +00002015 certtype = {
2016 ssl.CERT_NONE: "CERT_NONE",
2017 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
2018 ssl.CERT_REQUIRED: "CERT_REQUIRED",
2019 }[certsreqs]
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002020 if support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +00002021 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +00002022 sys.stdout.write(formatstr %
2023 (ssl.get_protocol_name(client_protocol),
2024 ssl.get_protocol_name(server_protocol),
2025 certtype))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002026 client_context = ssl.SSLContext(client_protocol)
2027 client_context.options |= client_options
2028 server_context = ssl.SSLContext(server_protocol)
2029 server_context.options |= server_options
2030
2031 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
2032 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
2033 # starting from OpenSSL 1.0.0 (see issue #8322).
2034 if client_context.protocol == ssl.PROTOCOL_SSLv23:
2035 client_context.set_ciphers("ALL")
2036
2037 for ctx in (client_context, server_context):
2038 ctx.verify_mode = certsreqs
2039 ctx.load_cert_chain(CERTFILE)
2040 ctx.load_verify_locations(CERTFILE)
Bill Janssen98d19da2007-09-10 21:51:02 +00002041 try:
Alex Gaynore98205d2014-09-04 13:33:22 -07002042 stats = server_params_test(client_context, server_context,
2043 chatty=False, connectionchatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +00002044 # Protocol mismatch can result in either an SSLError, or a
2045 # "Connection reset by peer" error.
2046 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +00002047 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +00002048 raise
Antoine Pitroudb187842010-04-27 10:32:58 +00002049 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +00002050 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +00002051 raise
Bill Janssen98d19da2007-09-10 21:51:02 +00002052 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +00002053 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +00002054 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +00002055 "Client protocol %s succeeded with server protocol %s!"
2056 % (ssl.get_protocol_name(client_protocol),
2057 ssl.get_protocol_name(server_protocol)))
Alex Gaynore98205d2014-09-04 13:33:22 -07002058 elif (expect_success is not True
2059 and expect_success != stats['version']):
2060 raise AssertionError("version mismatch: expected %r, got %r"
2061 % (expect_success, stats['version']))
Bill Janssen98d19da2007-09-10 21:51:02 +00002062
2063
Bill Janssen934b16d2008-06-28 22:19:33 +00002064 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +00002065
Antoine Pitroud75efd92010-08-04 17:38:33 +00002066 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002067 def test_echo(self):
2068 """Basic test of an SSL client connecting to a server"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002069 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002070 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002071 for protocol in PROTOCOLS:
2072 context = ssl.SSLContext(protocol)
2073 context.load_cert_chain(CERTFILE)
2074 server_params_test(context, context,
2075 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00002076
Antoine Pitrou3945c862010-04-28 21:11:01 +00002077 def test_getpeercert(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002078 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002079 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002080 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2081 context.verify_mode = ssl.CERT_REQUIRED
2082 context.load_verify_locations(CERTFILE)
2083 context.load_cert_chain(CERTFILE)
2084 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002085 with server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002086 s = context.wrap_socket(socket.socket(),
2087 do_handshake_on_connect=False)
Antoine Pitroudb187842010-04-27 10:32:58 +00002088 s.connect((HOST, server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002089 # getpeercert() raise ValueError while the handshake isn't
2090 # done.
2091 with self.assertRaises(ValueError):
2092 s.getpeercert()
2093 s.do_handshake()
Antoine Pitroudb187842010-04-27 10:32:58 +00002094 cert = s.getpeercert()
2095 self.assertTrue(cert, "Can't get peer certificate.")
2096 cipher = s.cipher()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002097 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002098 sys.stdout.write(pprint.pformat(cert) + '\n')
2099 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2100 if 'subject' not in cert:
2101 self.fail("No subject field in certificate: %s." %
2102 pprint.pformat(cert))
2103 if ((('organizationName', 'Python Software Foundation'),)
2104 not in cert['subject']):
2105 self.fail(
2106 "Missing or invalid 'organizationName' field in certificate subject; "
2107 "should be 'Python Software Foundation'.")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002108 self.assertIn('notBefore', cert)
2109 self.assertIn('notAfter', cert)
2110 before = ssl.cert_time_to_seconds(cert['notBefore'])
2111 after = ssl.cert_time_to_seconds(cert['notAfter'])
2112 self.assertLess(before, after)
Antoine Pitroudb187842010-04-27 10:32:58 +00002113 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00002114
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002115 @unittest.skipUnless(have_verify_flags(),
2116 "verify_flags need OpenSSL > 0.9.8")
2117 def test_crl_check(self):
2118 if support.verbose:
2119 sys.stdout.write("\n")
2120
2121 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2122 server_context.load_cert_chain(SIGNED_CERTFILE)
2123
2124 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2125 context.verify_mode = ssl.CERT_REQUIRED
2126 context.load_verify_locations(SIGNING_CA)
Benjamin Petersond86699f2015-03-04 23:18:48 -05002127 tf = getattr(ssl, "VERIFY_X509_TRUSTED_FIRST", 0)
2128 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT | tf)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002129
2130 # VERIFY_DEFAULT should pass
2131 server = ThreadedEchoServer(context=server_context, chatty=True)
2132 with server:
2133 with closing(context.wrap_socket(socket.socket())) as s:
2134 s.connect((HOST, server.port))
2135 cert = s.getpeercert()
2136 self.assertTrue(cert, "Can't get peer certificate.")
2137
2138 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
2139 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
2140
2141 server = ThreadedEchoServer(context=server_context, chatty=True)
2142 with server:
2143 with closing(context.wrap_socket(socket.socket())) as s:
2144 with self.assertRaisesRegexp(ssl.SSLError,
2145 "certificate verify failed"):
2146 s.connect((HOST, server.port))
2147
2148 # now load a CRL file. The CRL file is signed by the CA.
2149 context.load_verify_locations(CRLFILE)
2150
2151 server = ThreadedEchoServer(context=server_context, chatty=True)
2152 with server:
2153 with closing(context.wrap_socket(socket.socket())) as s:
2154 s.connect((HOST, server.port))
2155 cert = s.getpeercert()
2156 self.assertTrue(cert, "Can't get peer certificate.")
2157
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002158 def test_check_hostname(self):
2159 if support.verbose:
2160 sys.stdout.write("\n")
2161
2162 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2163 server_context.load_cert_chain(SIGNED_CERTFILE)
2164
2165 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2166 context.verify_mode = ssl.CERT_REQUIRED
2167 context.check_hostname = True
2168 context.load_verify_locations(SIGNING_CA)
2169
2170 # correct hostname should verify
2171 server = ThreadedEchoServer(context=server_context, chatty=True)
2172 with server:
2173 with closing(context.wrap_socket(socket.socket(),
2174 server_hostname="localhost")) as s:
2175 s.connect((HOST, server.port))
2176 cert = s.getpeercert()
2177 self.assertTrue(cert, "Can't get peer certificate.")
2178
2179 # incorrect hostname should raise an exception
2180 server = ThreadedEchoServer(context=server_context, chatty=True)
2181 with server:
2182 with closing(context.wrap_socket(socket.socket(),
2183 server_hostname="invalid")) as s:
2184 with self.assertRaisesRegexp(ssl.CertificateError,
2185 "hostname 'invalid' doesn't match u?'localhost'"):
2186 s.connect((HOST, server.port))
2187
2188 # missing server_hostname arg should cause an exception, too
2189 server = ThreadedEchoServer(context=server_context, chatty=True)
2190 with server:
2191 with closing(socket.socket()) as s:
2192 with self.assertRaisesRegexp(ValueError,
2193 "check_hostname requires server_hostname"):
2194 context.wrap_socket(s)
2195
Martin Panterfd8e8502016-01-30 02:36:00 +00002196 def test_wrong_cert(self):
Martin Panter886aba42016-02-01 21:58:11 +00002197 """Connecting when the server rejects the client's certificate
2198
2199 Launch a server with CERT_REQUIRED, and check that trying to
2200 connect to it with a wrong client certificate fails.
2201 """
2202 certfile = os.path.join(os.path.dirname(__file__) or os.curdir,
2203 "wrongcert.pem")
2204 server = ThreadedEchoServer(CERTFILE,
2205 certreqs=ssl.CERT_REQUIRED,
2206 cacerts=CERTFILE, chatty=False,
2207 connectionchatty=False)
2208 with server, \
2209 closing(socket.socket()) as sock, \
2210 closing(ssl.wrap_socket(sock,
2211 certfile=certfile,
2212 ssl_version=ssl.PROTOCOL_TLSv1)) as s:
2213 try:
2214 # Expect either an SSL error about the server rejecting
2215 # the connection, or a low-level connection reset (which
2216 # sometimes happens on Windows)
2217 s.connect((HOST, server.port))
2218 except ssl.SSLError as e:
2219 if support.verbose:
2220 sys.stdout.write("\nSSLError is %r\n" % e)
2221 except socket.error as e:
2222 if e.errno != errno.ECONNRESET:
2223 raise
2224 if support.verbose:
2225 sys.stdout.write("\nsocket.error is %r\n" % e)
2226 else:
2227 self.fail("Use of invalid cert should have failed!")
Bill Janssen98d19da2007-09-10 21:51:02 +00002228
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002229 def test_rude_shutdown(self):
2230 """A brutal shutdown of an SSL server should raise an OSError
2231 in the client when attempting handshake.
2232 """
2233 listener_ready = threading.Event()
2234 listener_gone = threading.Event()
2235
2236 s = socket.socket()
2237 port = support.bind_port(s, HOST)
2238
2239 # `listener` runs in a thread. It sits in an accept() until
2240 # the main thread connects. Then it rudely closes the socket,
2241 # and sets Event `listener_gone` to let the main thread know
2242 # the socket is gone.
2243 def listener():
2244 s.listen(5)
2245 listener_ready.set()
2246 newsock, addr = s.accept()
2247 newsock.close()
2248 s.close()
2249 listener_gone.set()
2250
2251 def connector():
2252 listener_ready.wait()
2253 with closing(socket.socket()) as c:
2254 c.connect((HOST, port))
2255 listener_gone.wait()
2256 try:
2257 ssl_sock = ssl.wrap_socket(c)
Benjamin Petersone208b572014-08-20 14:49:08 -05002258 except socket.error:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002259 pass
2260 else:
2261 self.fail('connecting to closed SSL socket should have failed')
2262
2263 t = threading.Thread(target=listener)
2264 t.start()
2265 try:
2266 connector()
2267 finally:
2268 t.join()
2269
Antoine Pitroud75efd92010-08-04 17:38:33 +00002270 @skip_if_broken_ubuntu_ssl
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002271 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2272 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou3945c862010-04-28 21:11:01 +00002273 def test_protocol_sslv2(self):
2274 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002275 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002276 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00002277 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2278 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2279 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitrou3b2afbb2014-01-09 19:52:12 +01002280 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002281 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
2282 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002283 # SSLv23 client with specific SSL options
2284 if no_sslv2_implies_sslv3_hello():
2285 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2286 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2287 client_options=ssl.OP_NO_SSLv2)
2288 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2289 client_options=ssl.OP_NO_SSLv3)
2290 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2291 client_options=ssl.OP_NO_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +00002292
Antoine Pitroud75efd92010-08-04 17:38:33 +00002293 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002294 def test_protocol_sslv23(self):
2295 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002296 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002297 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002298 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2299 try:
2300 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
2301 except socket.error as x:
2302 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2303 if support.verbose:
2304 sys.stdout.write(
2305 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2306 % str(x))
Benjamin Peterson60766c42014-12-05 21:59:35 -05002307 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Peterson10aaca92015-11-11 22:38:41 -08002308 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002309 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Alex Gaynore98205d2014-09-04 13:33:22 -07002310 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Bill Janssen98d19da2007-09-10 21:51:02 +00002311
Benjamin Peterson60766c42014-12-05 21:59:35 -05002312 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Peterson10aaca92015-11-11 22:38:41 -08002313 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_OPTIONAL)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002314 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Alex Gaynore98205d2014-09-04 13:33:22 -07002315 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00002316
Benjamin Peterson60766c42014-12-05 21:59:35 -05002317 if hasattr(ssl, 'PROTOCOL_SSLv3'):
Benjamin Peterson10aaca92015-11-11 22:38:41 -08002318 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False, ssl.CERT_REQUIRED)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002319 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Alex Gaynore98205d2014-09-04 13:33:22 -07002320 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00002321
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002322 # Server with specific SSL options
Benjamin Peterson60766c42014-12-05 21:59:35 -05002323 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2324 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002325 server_options=ssl.OP_NO_SSLv3)
2326 # Will choose TLSv1
2327 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2328 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2329 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2330 server_options=ssl.OP_NO_TLSv1)
2331
2332
Antoine Pitroud75efd92010-08-04 17:38:33 +00002333 @skip_if_broken_ubuntu_ssl
Benjamin Peterson60766c42014-12-05 21:59:35 -05002334 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv3'),
2335 "OpenSSL is compiled without SSLv3 support")
Antoine Pitrou3945c862010-04-28 21:11:01 +00002336 def test_protocol_sslv3(self):
2337 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002338 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002339 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002340 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2341 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2342 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02002343 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2344 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002345 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2346 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002347 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002348 if no_sslv2_implies_sslv3_hello():
2349 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Benjamin Peterson10aaca92015-11-11 22:38:41 -08002350 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23,
2351 False, client_options=ssl.OP_NO_SSLv2)
Bill Janssen98d19da2007-09-10 21:51:02 +00002352
Antoine Pitroud75efd92010-08-04 17:38:33 +00002353 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002354 def test_protocol_tlsv1(self):
2355 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002356 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002357 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002358 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2359 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2360 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02002361 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2362 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Benjamin Peterson60766c42014-12-05 21:59:35 -05002363 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2364 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002365 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2366 client_options=ssl.OP_NO_TLSv1)
2367
2368 @skip_if_broken_ubuntu_ssl
2369 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2370 "TLS version 1.1 not supported.")
2371 def test_protocol_tlsv1_1(self):
2372 """Connecting to a TLSv1.1 server with various client options.
2373 Testing against older TLS versions."""
2374 if support.verbose:
2375 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002376 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002377 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2378 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
Benjamin Peterson60766c42014-12-05 21:59:35 -05002379 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2380 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002381 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2382 client_options=ssl.OP_NO_TLSv1_1)
2383
Alex Gaynore98205d2014-09-04 13:33:22 -07002384 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002385 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2386 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2387
2388
2389 @skip_if_broken_ubuntu_ssl
2390 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2391 "TLS version 1.2 not supported.")
2392 def test_protocol_tlsv1_2(self):
2393 """Connecting to a TLSv1.2 server with various client options.
2394 Testing against older TLS versions."""
2395 if support.verbose:
2396 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002397 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002398 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2399 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2400 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2401 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
Benjamin Peterson60766c42014-12-05 21:59:35 -05002402 if hasattr(ssl, 'PROTOCOL_SSLv3'):
2403 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002404 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2405 client_options=ssl.OP_NO_TLSv1_2)
2406
Alex Gaynore98205d2014-09-04 13:33:22 -07002407 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002408 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2409 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2410 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2411 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00002412
Antoine Pitrou3945c862010-04-28 21:11:01 +00002413 def test_starttls(self):
2414 """Switching from clear text to encrypted and back again."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002415 msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00002416
Trent Nelsone41b0062008-04-08 23:47:30 +00002417 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00002418 ssl_version=ssl.PROTOCOL_TLSv1,
2419 starttls_server=True,
2420 chatty=True,
2421 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00002422 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002423 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00002424 s = socket.socket()
2425 s.setblocking(1)
2426 s.connect((HOST, server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002427 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002428 sys.stdout.write("\n")
2429 for indata in msgs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002430 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002431 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002432 " client: sending %r...\n" % indata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002433 if wrapped:
2434 conn.write(indata)
2435 outdata = conn.read()
2436 else:
2437 s.send(indata)
2438 outdata = s.recv(1024)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002439 msg = outdata.strip().lower()
2440 if indata == b"STARTTLS" and msg.startswith(b"ok"):
Antoine Pitrou3945c862010-04-28 21:11:01 +00002441 # STARTTLS ok, switch to secure mode
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002442 if support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00002443 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002444 " client: read %r from server, starting TLS...\n"
2445 % msg)
Antoine Pitroudb187842010-04-27 10:32:58 +00002446 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
2447 wrapped = True
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002448 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
Antoine Pitrou3945c862010-04-28 21:11:01 +00002449 # ENDTLS ok, switch back to clear text
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002450 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002451 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002452 " client: read %r from server, ending TLS...\n"
2453 % msg)
Antoine Pitroudb187842010-04-27 10:32:58 +00002454 s = conn.unwrap()
2455 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00002456 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002457 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002458 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002459 " client: read %r from server\n" % msg)
2460 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002461 sys.stdout.write(" client: closing connection.\n")
2462 if wrapped:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002463 conn.write(b"over\n")
Antoine Pitroudb187842010-04-27 10:32:58 +00002464 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002465 s.send(b"over\n")
2466 if wrapped:
2467 conn.close()
2468 else:
2469 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00002470
Antoine Pitrou3945c862010-04-28 21:11:01 +00002471 def test_socketserver(self):
2472 """Using a SocketServer to create and manage SSL connections."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002473 server = make_https_server(self, certfile=CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00002474 # try to connect
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002475 if support.verbose:
2476 sys.stdout.write('\n')
2477 with open(CERTFILE, 'rb') as f:
2478 d1 = f.read()
2479 d2 = ''
2480 # now fetch the same data from the HTTPS server
Benjamin Petersonfcfb18e2014-11-23 11:42:45 -06002481 url = 'https://localhost:%d/%s' % (
2482 server.port, os.path.split(CERTFILE)[1])
2483 context = ssl.create_default_context(cafile=CERTFILE)
Benjamin Petersonb0609ec2014-11-23 11:52:46 -06002484 f = urllib2.urlopen(url, context=context)
Bill Janssen296a59d2007-09-16 22:06:00 +00002485 try:
Bill Janssen296a59d2007-09-16 22:06:00 +00002486 dlen = f.info().getheader("content-length")
2487 if dlen and (int(dlen) > 0):
2488 d2 = f.read(int(dlen))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002489 if support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00002490 sys.stdout.write(
2491 " client: read %d bytes from remote server '%s'\n"
2492 % (len(d2), server))
Bill Janssen296a59d2007-09-16 22:06:00 +00002493 finally:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002494 f.close()
2495 self.assertEqual(d1, d2)
Bill Janssen934b16d2008-06-28 22:19:33 +00002496
Antoine Pitrou3945c862010-04-28 21:11:01 +00002497 def test_asyncore_server(self):
2498 """Check the example asyncore integration."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002499 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00002500 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002501
2502 indata = b"FOO\n"
Bill Janssen934b16d2008-06-28 22:19:33 +00002503 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002504 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00002505 s = ssl.wrap_socket(socket.socket())
2506 s.connect(('127.0.0.1', server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002507 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002508 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002509 " client: sending %r...\n" % indata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002510 s.write(indata)
2511 outdata = s.read()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002512 if support.verbose:
2513 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002514 if outdata != indata.lower():
2515 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002516 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2517 % (outdata[:20], len(outdata),
2518 indata[:20].lower(), len(indata)))
2519 s.write(b"over\n")
2520 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002521 sys.stdout.write(" client: closing connection.\n")
2522 s.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002523 if support.verbose:
2524 sys.stdout.write(" client: connection closed.\n")
Bill Janssen934b16d2008-06-28 22:19:33 +00002525
Antoine Pitrou3945c862010-04-28 21:11:01 +00002526 def test_recv_send(self):
2527 """Test recv(), send() and friends."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002528 if support.verbose:
Bill Janssen61c001a2008-09-08 16:37:24 +00002529 sys.stdout.write("\n")
2530
2531 server = ThreadedEchoServer(CERTFILE,
2532 certreqs=ssl.CERT_NONE,
2533 ssl_version=ssl.PROTOCOL_TLSv1,
2534 cacerts=CERTFILE,
2535 chatty=True,
2536 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002537 with server:
2538 s = ssl.wrap_socket(socket.socket(),
2539 server_side=False,
2540 certfile=CERTFILE,
2541 ca_certs=CERTFILE,
2542 cert_reqs=ssl.CERT_NONE,
2543 ssl_version=ssl.PROTOCOL_TLSv1)
2544 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00002545 # helper methods for standardising recv* method signatures
2546 def _recv_into():
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002547 b = bytearray(b"\0"*100)
Bill Janssen61c001a2008-09-08 16:37:24 +00002548 count = s.recv_into(b)
2549 return b[:count]
2550
2551 def _recvfrom_into():
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002552 b = bytearray(b"\0"*100)
Bill Janssen61c001a2008-09-08 16:37:24 +00002553 count, addr = s.recvfrom_into(b)
2554 return b[:count]
2555
2556 # (name, method, whether to expect success, *args)
2557 send_methods = [
2558 ('send', s.send, True, []),
2559 ('sendto', s.sendto, False, ["some.address"]),
2560 ('sendall', s.sendall, True, []),
2561 ]
2562 recv_methods = [
2563 ('recv', s.recv, True, []),
2564 ('recvfrom', s.recvfrom, False, ["some.address"]),
2565 ('recv_into', _recv_into, True, []),
2566 ('recvfrom_into', _recvfrom_into, False, []),
2567 ]
2568 data_prefix = u"PREFIX_"
2569
2570 for meth_name, send_meth, expect_success, args in send_methods:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002571 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen61c001a2008-09-08 16:37:24 +00002572 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002573 send_meth(indata, *args)
Bill Janssen61c001a2008-09-08 16:37:24 +00002574 outdata = s.read()
Bill Janssen61c001a2008-09-08 16:37:24 +00002575 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002576 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002577 "While sending with <<{name:s}>> bad data "
2578 "<<{outdata:r}>> ({nout:d}) received; "
2579 "expected <<{indata:r}>> ({nin:d})\n".format(
2580 name=meth_name, outdata=outdata[:20],
2581 nout=len(outdata),
2582 indata=indata[:20], nin=len(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002583 )
2584 )
2585 except ValueError as e:
2586 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002587 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002588 "Failed to send with method <<{name:s}>>; "
2589 "expected to succeed.\n".format(name=meth_name)
Bill Janssen61c001a2008-09-08 16:37:24 +00002590 )
2591 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002592 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002593 "Method <<{name:s}>> failed with unexpected "
2594 "exception message: {exp:s}\n".format(
2595 name=meth_name, exp=e
Bill Janssen61c001a2008-09-08 16:37:24 +00002596 )
2597 )
2598
2599 for meth_name, recv_meth, expect_success, args in recv_methods:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002600 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen61c001a2008-09-08 16:37:24 +00002601 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002602 s.send(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002603 outdata = recv_meth(*args)
Bill Janssen61c001a2008-09-08 16:37:24 +00002604 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002605 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002606 "While receiving with <<{name:s}>> bad data "
2607 "<<{outdata:r}>> ({nout:d}) received; "
2608 "expected <<{indata:r}>> ({nin:d})\n".format(
2609 name=meth_name, outdata=outdata[:20],
2610 nout=len(outdata),
2611 indata=indata[:20], nin=len(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002612 )
2613 )
2614 except ValueError as e:
2615 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002616 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002617 "Failed to receive with method <<{name:s}>>; "
2618 "expected to succeed.\n".format(name=meth_name)
Bill Janssen61c001a2008-09-08 16:37:24 +00002619 )
2620 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002621 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002622 "Method <<{name:s}>> failed with unexpected "
2623 "exception message: {exp:s}\n".format(
2624 name=meth_name, exp=e
Bill Janssen61c001a2008-09-08 16:37:24 +00002625 )
2626 )
2627 # consume data
2628 s.read()
2629
Martin Panterd524b702016-03-28 00:22:09 +00002630 # read(-1, buffer) is supported, even though read(-1) is not
Martin Panter8c6849b2016-07-11 00:17:13 +00002631 data = b"data"
Martin Panterb8089b42016-03-27 05:35:19 +00002632 s.send(data)
2633 buffer = bytearray(len(data))
2634 self.assertEqual(s.read(-1, buffer), len(data))
2635 self.assertEqual(buffer, data)
2636
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002637 s.write(b"over\n")
Martin Panterb8089b42016-03-27 05:35:19 +00002638
2639 self.assertRaises(ValueError, s.recv, -1)
2640 self.assertRaises(ValueError, s.read, -1)
2641
Bill Janssen61c001a2008-09-08 16:37:24 +00002642 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00002643
Martin Panter8c6849b2016-07-11 00:17:13 +00002644 def test_recv_zero(self):
2645 server = ThreadedEchoServer(CERTFILE)
2646 server.__enter__()
2647 self.addCleanup(server.__exit__, None, None)
2648 s = socket.create_connection((HOST, server.port))
2649 self.addCleanup(s.close)
2650 s = ssl.wrap_socket(s, suppress_ragged_eofs=False)
2651 self.addCleanup(s.close)
2652
2653 # recv/read(0) should return no data
2654 s.send(b"data")
2655 self.assertEqual(s.recv(0), b"")
2656 self.assertEqual(s.read(0), b"")
2657 self.assertEqual(s.read(), b"data")
2658
2659 # Should not block if the other end sends no data
2660 s.setblocking(False)
2661 self.assertEqual(s.recv(0), b"")
2662 self.assertEqual(s.recv_into(bytearray()), 0)
2663
Antoine Pitroufc69af12010-04-24 20:04:58 +00002664 def test_handshake_timeout(self):
2665 # Issue #5103: SSL handshake must respect the socket timeout
2666 server = socket.socket(socket.AF_INET)
2667 host = "127.0.0.1"
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002668 port = support.bind_port(server)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002669 started = threading.Event()
2670 finish = False
2671
2672 def serve():
2673 server.listen(5)
2674 started.set()
2675 conns = []
2676 while not finish:
2677 r, w, e = select.select([server], [], [], 0.1)
2678 if server in r:
2679 # Let the socket hang around rather than having
2680 # it closed by garbage collection.
2681 conns.append(server.accept()[0])
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002682 for sock in conns:
2683 sock.close()
Antoine Pitroufc69af12010-04-24 20:04:58 +00002684
2685 t = threading.Thread(target=serve)
2686 t.start()
2687 started.wait()
2688
2689 try:
2690 try:
2691 c = socket.socket(socket.AF_INET)
2692 c.settimeout(0.2)
2693 c.connect((host, port))
2694 # Will attempt handshake and time out
2695 self.assertRaisesRegexp(ssl.SSLError, "timed out",
2696 ssl.wrap_socket, c)
2697 finally:
2698 c.close()
2699 try:
2700 c = socket.socket(socket.AF_INET)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002701 c = ssl.wrap_socket(c)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002702 c.settimeout(0.2)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002703 # Will attempt handshake and time out
2704 self.assertRaisesRegexp(ssl.SSLError, "timed out",
2705 c.connect, (host, port))
2706 finally:
2707 c.close()
2708 finally:
2709 finish = True
2710 t.join()
2711 server.close()
2712
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002713 def test_server_accept(self):
2714 # Issue #16357: accept() on a SSLSocket created through
2715 # SSLContext.wrap_socket().
2716 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2717 context.verify_mode = ssl.CERT_REQUIRED
2718 context.load_verify_locations(CERTFILE)
2719 context.load_cert_chain(CERTFILE)
2720 server = socket.socket(socket.AF_INET)
2721 host = "127.0.0.1"
2722 port = support.bind_port(server)
2723 server = context.wrap_socket(server, server_side=True)
2724
2725 evt = threading.Event()
2726 remote = [None]
2727 peer = [None]
2728 def serve():
2729 server.listen(5)
2730 # Block on the accept and wait on the connection to close.
2731 evt.set()
2732 remote[0], peer[0] = server.accept()
2733 remote[0].recv(1)
2734
2735 t = threading.Thread(target=serve)
2736 t.start()
2737 # Client wait until server setup and perform a connect.
2738 evt.wait()
2739 client = context.wrap_socket(socket.socket())
2740 client.connect((host, port))
2741 client_addr = client.getsockname()
2742 client.close()
2743 t.join()
2744 remote[0].close()
2745 server.close()
2746 # Sanity checks.
2747 self.assertIsInstance(remote[0], ssl.SSLSocket)
2748 self.assertEqual(peer[0], client_addr)
2749
2750 def test_getpeercert_enotconn(self):
2751 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2752 with closing(context.wrap_socket(socket.socket())) as sock:
2753 with self.assertRaises(socket.error) as cm:
2754 sock.getpeercert()
2755 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2756
2757 def test_do_handshake_enotconn(self):
2758 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2759 with closing(context.wrap_socket(socket.socket())) as sock:
2760 with self.assertRaises(socket.error) as cm:
2761 sock.do_handshake()
2762 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2763
Antoine Pitroud76088d2012-01-03 22:46:48 +01002764 def test_default_ciphers(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002765 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2766 try:
2767 # Force a set of weak ciphers on our client context
2768 context.set_ciphers("DES")
2769 except ssl.SSLError:
2770 self.skipTest("no DES cipher available")
Antoine Pitroud76088d2012-01-03 22:46:48 +01002771 with ThreadedEchoServer(CERTFILE,
2772 ssl_version=ssl.PROTOCOL_SSLv23,
2773 chatty=False) as server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002774 with closing(context.wrap_socket(socket.socket())) as s:
2775 with self.assertRaises(ssl.SSLError):
Antoine Pitroud76088d2012-01-03 22:46:48 +01002776 s.connect((HOST, server.port))
Antoine Pitroud76088d2012-01-03 22:46:48 +01002777 self.assertIn("no shared cipher", str(server.conn_errors[0]))
2778
Alex Gaynore98205d2014-09-04 13:33:22 -07002779 def test_version_basic(self):
2780 """
2781 Basic tests for SSLSocket.version().
2782 More tests are done in the test_protocol_*() methods.
2783 """
2784 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2785 with ThreadedEchoServer(CERTFILE,
2786 ssl_version=ssl.PROTOCOL_TLSv1,
2787 chatty=False) as server:
2788 with closing(context.wrap_socket(socket.socket())) as s:
2789 self.assertIs(s.version(), None)
2790 s.connect((HOST, server.port))
Christian Heimesc2fc7c42016-09-05 23:37:13 +02002791 self.assertEqual(s.version(), 'TLSv1')
Alex Gaynore98205d2014-09-04 13:33:22 -07002792 self.assertIs(s.version(), None)
2793
Christian Heimesb9a860f2017-09-07 22:31:17 -07002794 @unittest.skipUnless(ssl.HAS_TLSv1_3,
2795 "test requires TLSv1.3 enabled OpenSSL")
2796 def test_tls1_3(self):
2797 context = ssl.SSLContext(ssl.PROTOCOL_TLS)
2798 context.load_cert_chain(CERTFILE)
2799 # disable all but TLS 1.3
2800 context.options |= (
2801 ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_TLSv1_2
2802 )
2803 with ThreadedEchoServer(context=context) as server:
2804 with context.wrap_socket(socket.socket()) as s:
2805 s.connect((HOST, server.port))
2806 self.assertIn(s.cipher()[0], [
2807 'TLS13-AES-256-GCM-SHA384',
2808 'TLS13-CHACHA20-POLY1305-SHA256',
2809 'TLS13-AES-128-GCM-SHA256',
2810 ])
2811
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002812 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
2813 def test_default_ecdh_curve(self):
2814 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
2815 # should be enabled by default on SSL contexts.
2816 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2817 context.load_cert_chain(CERTFILE)
2818 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
2819 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
2820 # our default cipher list should prefer ECDH-based ciphers
2821 # automatically.
2822 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
2823 context.set_ciphers("ECCdraft:ECDH")
2824 with ThreadedEchoServer(context=context) as server:
2825 with closing(context.wrap_socket(socket.socket())) as s:
2826 s.connect((HOST, server.port))
2827 self.assertIn("ECDH", s.cipher()[0])
2828
2829 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
2830 "'tls-unique' channel binding not available")
2831 def test_tls_unique_channel_binding(self):
2832 """Test tls-unique channel binding."""
2833 if support.verbose:
2834 sys.stdout.write("\n")
2835
2836 server = ThreadedEchoServer(CERTFILE,
2837 certreqs=ssl.CERT_NONE,
2838 ssl_version=ssl.PROTOCOL_TLSv1,
2839 cacerts=CERTFILE,
2840 chatty=True,
2841 connectionchatty=False)
2842 with server:
2843 s = ssl.wrap_socket(socket.socket(),
2844 server_side=False,
2845 certfile=CERTFILE,
2846 ca_certs=CERTFILE,
2847 cert_reqs=ssl.CERT_NONE,
2848 ssl_version=ssl.PROTOCOL_TLSv1)
2849 s.connect((HOST, server.port))
2850 # get the data
2851 cb_data = s.get_channel_binding("tls-unique")
2852 if support.verbose:
2853 sys.stdout.write(" got channel binding data: {0!r}\n"
2854 .format(cb_data))
2855
2856 # check if it is sane
2857 self.assertIsNotNone(cb_data)
2858 self.assertEqual(len(cb_data), 12) # True for TLSv1
2859
2860 # and compare with the peers version
2861 s.write(b"CB tls-unique\n")
2862 peer_data_repr = s.read().strip()
2863 self.assertEqual(peer_data_repr,
2864 repr(cb_data).encode("us-ascii"))
2865 s.close()
2866
2867 # now, again
2868 s = ssl.wrap_socket(socket.socket(),
2869 server_side=False,
2870 certfile=CERTFILE,
2871 ca_certs=CERTFILE,
2872 cert_reqs=ssl.CERT_NONE,
2873 ssl_version=ssl.PROTOCOL_TLSv1)
2874 s.connect((HOST, server.port))
2875 new_cb_data = s.get_channel_binding("tls-unique")
2876 if support.verbose:
2877 sys.stdout.write(" got another channel binding data: {0!r}\n"
2878 .format(new_cb_data))
2879 # is it really unique
2880 self.assertNotEqual(cb_data, new_cb_data)
2881 self.assertIsNotNone(cb_data)
2882 self.assertEqual(len(cb_data), 12) # True for TLSv1
2883 s.write(b"CB tls-unique\n")
2884 peer_data_repr = s.read().strip()
2885 self.assertEqual(peer_data_repr,
2886 repr(new_cb_data).encode("us-ascii"))
2887 s.close()
2888
2889 def test_compression(self):
2890 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2891 context.load_cert_chain(CERTFILE)
2892 stats = server_params_test(context, context,
2893 chatty=True, connectionchatty=True)
2894 if support.verbose:
2895 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
2896 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
2897
2898 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
2899 "ssl.OP_NO_COMPRESSION needed for this test")
2900 def test_compression_disabled(self):
2901 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2902 context.load_cert_chain(CERTFILE)
2903 context.options |= ssl.OP_NO_COMPRESSION
2904 stats = server_params_test(context, context,
2905 chatty=True, connectionchatty=True)
2906 self.assertIs(stats['compression'], None)
2907
2908 def test_dh_params(self):
2909 # Check we can get a connection with ephemeral Diffie-Hellman
2910 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2911 context.load_cert_chain(CERTFILE)
2912 context.load_dh_params(DHFILE)
2913 context.set_ciphers("kEDH")
2914 stats = server_params_test(context, context,
2915 chatty=True, connectionchatty=True)
2916 cipher = stats["cipher"][0]
2917 parts = cipher.split("-")
2918 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
2919 self.fail("Non-DH cipher: " + cipher[0])
2920
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002921 def test_selected_alpn_protocol(self):
2922 # selected_alpn_protocol() is None unless ALPN is used.
2923 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2924 context.load_cert_chain(CERTFILE)
2925 stats = server_params_test(context, context,
2926 chatty=True, connectionchatty=True)
2927 self.assertIs(stats['client_alpn_protocol'], None)
2928
2929 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support required")
2930 def test_selected_alpn_protocol_if_server_uses_alpn(self):
2931 # selected_alpn_protocol() is None unless ALPN is used by the client.
2932 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2933 client_context.load_verify_locations(CERTFILE)
2934 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2935 server_context.load_cert_chain(CERTFILE)
2936 server_context.set_alpn_protocols(['foo', 'bar'])
2937 stats = server_params_test(client_context, server_context,
2938 chatty=True, connectionchatty=True)
2939 self.assertIs(stats['client_alpn_protocol'], None)
2940
2941 @unittest.skipUnless(ssl.HAS_ALPN, "ALPN support needed for this test")
2942 def test_alpn_protocols(self):
2943 server_protocols = ['foo', 'bar', 'milkshake']
2944 protocol_tests = [
2945 (['foo', 'bar'], 'foo'),
Benjamin Petersonaa707582015-01-23 17:30:26 -05002946 (['bar', 'foo'], 'foo'),
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002947 (['milkshake'], 'milkshake'),
Benjamin Petersonaa707582015-01-23 17:30:26 -05002948 (['http/3.0', 'http/4.0'], None)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002949 ]
2950 for client_protocols, expected in protocol_tests:
Christian Heimesc2fc7c42016-09-05 23:37:13 +02002951 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002952 server_context.load_cert_chain(CERTFILE)
2953 server_context.set_alpn_protocols(server_protocols)
Christian Heimesc2fc7c42016-09-05 23:37:13 +02002954 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002955 client_context.load_cert_chain(CERTFILE)
2956 client_context.set_alpn_protocols(client_protocols)
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002957
Christian Heimesc2fc7c42016-09-05 23:37:13 +02002958 try:
2959 stats = server_params_test(client_context,
2960 server_context,
2961 chatty=True,
2962 connectionchatty=True)
2963 except ssl.SSLError as e:
2964 stats = e
2965
Christian Heimes05b7d9c2017-08-15 10:55:03 +02002966 if (expected is None and IS_OPENSSL_1_1
2967 and ssl.OPENSSL_VERSION_INFO < (1, 1, 0, 6)):
2968 # OpenSSL 1.1.0 to 1.1.0e raises handshake error
Christian Heimesc2fc7c42016-09-05 23:37:13 +02002969 self.assertIsInstance(stats, ssl.SSLError)
2970 else:
2971 msg = "failed trying %s (s) and %s (c).\n" \
2972 "was expecting %s, but got %%s from the %%s" \
2973 % (str(server_protocols), str(client_protocols),
2974 str(expected))
2975 client_result = stats['client_alpn_protocol']
2976 self.assertEqual(client_result, expected,
2977 msg % (client_result, "client"))
2978 server_result = stats['server_alpn_protocols'][-1] \
2979 if len(stats['server_alpn_protocols']) else 'nothing'
2980 self.assertEqual(server_result, expected,
2981 msg % (server_result, "server"))
Benjamin Petersonb10bfbe2015-01-23 16:35:37 -05002982
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002983 def test_selected_npn_protocol(self):
2984 # selected_npn_protocol() is None unless NPN is used
2985 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2986 context.load_cert_chain(CERTFILE)
2987 stats = server_params_test(context, context,
2988 chatty=True, connectionchatty=True)
2989 self.assertIs(stats['client_npn_protocol'], None)
2990
2991 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
2992 def test_npn_protocols(self):
2993 server_protocols = ['http/1.1', 'spdy/2']
2994 protocol_tests = [
2995 (['http/1.1', 'spdy/2'], 'http/1.1'),
2996 (['spdy/2', 'http/1.1'], 'http/1.1'),
2997 (['spdy/2', 'test'], 'spdy/2'),
2998 (['abc', 'def'], 'abc')
2999 ]
3000 for client_protocols, expected in protocol_tests:
3001 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3002 server_context.load_cert_chain(CERTFILE)
3003 server_context.set_npn_protocols(server_protocols)
3004 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3005 client_context.load_cert_chain(CERTFILE)
3006 client_context.set_npn_protocols(client_protocols)
3007 stats = server_params_test(client_context, server_context,
3008 chatty=True, connectionchatty=True)
3009
3010 msg = "failed trying %s (s) and %s (c).\n" \
3011 "was expecting %s, but got %%s from the %%s" \
3012 % (str(server_protocols), str(client_protocols),
3013 str(expected))
3014 client_result = stats['client_npn_protocol']
3015 self.assertEqual(client_result, expected, msg % (client_result, "client"))
3016 server_result = stats['server_npn_protocols'][-1] \
3017 if len(stats['server_npn_protocols']) else 'nothing'
3018 self.assertEqual(server_result, expected, msg % (server_result, "server"))
3019
3020 def sni_contexts(self):
3021 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3022 server_context.load_cert_chain(SIGNED_CERTFILE)
3023 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3024 other_context.load_cert_chain(SIGNED_CERTFILE2)
3025 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
3026 client_context.verify_mode = ssl.CERT_REQUIRED
3027 client_context.load_verify_locations(SIGNING_CA)
3028 return server_context, other_context, client_context
3029
3030 def check_common_name(self, stats, name):
3031 cert = stats['peercert']
3032 self.assertIn((('commonName', name),), cert['subject'])
3033
3034 @needs_sni
3035 def test_sni_callback(self):
3036 calls = []
3037 server_context, other_context, client_context = self.sni_contexts()
3038
3039 def servername_cb(ssl_sock, server_name, initial_context):
3040 calls.append((server_name, initial_context))
3041 if server_name is not None:
3042 ssl_sock.context = other_context
3043 server_context.set_servername_callback(servername_cb)
3044
3045 stats = server_params_test(client_context, server_context,
3046 chatty=True,
3047 sni_name='supermessage')
3048 # The hostname was fetched properly, and the certificate was
3049 # changed for the connection.
3050 self.assertEqual(calls, [("supermessage", server_context)])
3051 # CERTFILE4 was selected
3052 self.check_common_name(stats, 'fakehostname')
3053
3054 calls = []
3055 # The callback is called with server_name=None
3056 stats = server_params_test(client_context, server_context,
3057 chatty=True,
3058 sni_name=None)
3059 self.assertEqual(calls, [(None, server_context)])
3060 self.check_common_name(stats, 'localhost')
3061
3062 # Check disabling the callback
3063 calls = []
3064 server_context.set_servername_callback(None)
3065
3066 stats = server_params_test(client_context, server_context,
3067 chatty=True,
3068 sni_name='notfunny')
3069 # Certificate didn't change
3070 self.check_common_name(stats, 'localhost')
3071 self.assertEqual(calls, [])
3072
3073 @needs_sni
3074 def test_sni_callback_alert(self):
3075 # Returning a TLS alert is reflected to the connecting client
3076 server_context, other_context, client_context = self.sni_contexts()
3077
3078 def cb_returning_alert(ssl_sock, server_name, initial_context):
3079 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
3080 server_context.set_servername_callback(cb_returning_alert)
3081
3082 with self.assertRaises(ssl.SSLError) as cm:
3083 stats = server_params_test(client_context, server_context,
3084 chatty=False,
3085 sni_name='supermessage')
3086 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
3087
3088 @needs_sni
3089 def test_sni_callback_raising(self):
3090 # Raising fails the connection with a TLS handshake failure alert.
3091 server_context, other_context, client_context = self.sni_contexts()
3092
3093 def cb_raising(ssl_sock, server_name, initial_context):
Serhiy Storchaka5312a7f2015-01-31 11:27:06 +02003094 1.0/0.0
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003095 server_context.set_servername_callback(cb_raising)
3096
3097 with self.assertRaises(ssl.SSLError) as cm, \
3098 support.captured_stderr() as stderr:
3099 stats = server_params_test(client_context, server_context,
3100 chatty=False,
3101 sni_name='supermessage')
3102 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
3103 self.assertIn("ZeroDivisionError", stderr.getvalue())
3104
3105 @needs_sni
3106 def test_sni_callback_wrong_return_type(self):
3107 # Returning the wrong return type terminates the TLS connection
3108 # with an internal error alert.
3109 server_context, other_context, client_context = self.sni_contexts()
3110
3111 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
3112 return "foo"
3113 server_context.set_servername_callback(cb_wrong_return_type)
3114
3115 with self.assertRaises(ssl.SSLError) as cm, \
3116 support.captured_stderr() as stderr:
3117 stats = server_params_test(client_context, server_context,
3118 chatty=False,
3119 sni_name='supermessage')
3120 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
3121 self.assertIn("TypeError", stderr.getvalue())
3122
3123 def test_read_write_after_close_raises_valuerror(self):
3124 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
3125 context.verify_mode = ssl.CERT_REQUIRED
3126 context.load_verify_locations(CERTFILE)
3127 context.load_cert_chain(CERTFILE)
3128 server = ThreadedEchoServer(context=context, chatty=False)
3129
3130 with server:
3131 s = context.wrap_socket(socket.socket())
3132 s.connect((HOST, server.port))
3133 s.close()
3134
3135 self.assertRaises(ValueError, s.read, 1024)
3136 self.assertRaises(ValueError, s.write, b'hello')
3137
Bill Janssen61c001a2008-09-08 16:37:24 +00003138
Neal Norwitz9eb9b102007-08-27 01:15:33 +00003139def test_main(verbose=False):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003140 if support.verbose:
3141 plats = {
3142 'Linux': platform.linux_distribution,
3143 'Mac': platform.mac_ver,
3144 'Windows': platform.win32_ver,
3145 }
3146 for name, func in plats.items():
3147 plat = func()
3148 if plat and plat[0]:
3149 plat = '%s %r' % (name, plat)
3150 break
3151 else:
3152 plat = repr(platform.platform())
3153 print("test_ssl: testing with %r %r" %
3154 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
3155 print(" under %s" % plat)
3156 print(" HAS_SNI = %r" % ssl.HAS_SNI)
3157 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
3158 try:
3159 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
3160 except AttributeError:
3161 pass
Bill Janssen296a59d2007-09-16 22:06:00 +00003162
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003163 for filename in [
Martin Panter71202bb2016-01-15 00:25:29 +00003164 CERTFILE, REMOTE_ROOT_CERT, BYTES_CERTFILE,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003165 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
3166 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
3167 BADCERT, BADKEY, EMPTYCERT]:
3168 if not os.path.exists(filename):
3169 raise support.TestFailed("Can't read certificate file %r" % filename)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00003170
Benjamin Peterson2f334562014-10-01 23:53:01 -04003171 tests = [ContextTests, BasicTests, BasicSocketTests, SSLErrorTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00003172
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003173 if support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00003174 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00003175
Bill Janssen98d19da2007-09-10 21:51:02 +00003176 if _have_threads:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003177 thread_info = support.threading_setup()
3178 if thread_info:
Bill Janssen934b16d2008-06-28 22:19:33 +00003179 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00003180
Antoine Pitrou3945c862010-04-28 21:11:01 +00003181 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003182 support.run_unittest(*tests)
Antoine Pitrou3945c862010-04-28 21:11:01 +00003183 finally:
3184 if _have_threads:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05003185 support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00003186
3187if __name__ == "__main__":
3188 test_main()