blob: 825b986475824b00064cf29075720423710df055 [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
Bill Janssen934b16d2008-06-28 22:19:33 +00007import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00008import socket
Bill Janssen934b16d2008-06-28 22:19:33 +00009import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000010import time
Benjamin Petersondaeb9252014-08-20 14:14:50 -050011import datetime
Antoine Pitroub558f172010-04-23 23:25:45 +000012import gc
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000013import os
Antoine Pitroub558f172010-04-23 23:25:45 +000014import errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000015import pprint
Benjamin Petersondaeb9252014-08-20 14:14:50 -050016import tempfile
17import urllib
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000018import traceback
Antoine Pitroudfb299b2010-04-23 22:54:59 +000019import weakref
Antoine Pitroud75efd92010-08-04 17:38:33 +000020import platform
Benjamin Petersondaeb9252014-08-20 14:14:50 -050021import functools
22from contextlib import closing
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000023
Benjamin Petersondaeb9252014-08-20 14:14:50 -050024ssl = support.import_module("ssl")
Bill Janssen296a59d2007-09-16 22:06:00 +000025
Benjamin Petersondaeb9252014-08-20 14:14:50 -050026PROTOCOLS = sorted(ssl._PROTOCOL_NAMES)
27HOST = support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000028
Benjamin Petersondaeb9252014-08-20 14:14:50 -050029def data_file(*name):
30 return os.path.join(os.path.dirname(__file__), *name)
31
32# The custom key and certificate files used in test_ssl are generated
33# using Lib/test/make_ssl_certs.py.
34# Other certificates are simply fetched from the Internet servers they
35# are meant to authenticate.
36
37CERTFILE = data_file("keycert.pem")
38BYTES_CERTFILE = CERTFILE.encode(sys.getfilesystemencoding())
39ONLYCERT = data_file("ssl_cert.pem")
40ONLYKEY = data_file("ssl_key.pem")
41BYTES_ONLYCERT = ONLYCERT.encode(sys.getfilesystemencoding())
42BYTES_ONLYKEY = ONLYKEY.encode(sys.getfilesystemencoding())
43CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
44ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
45KEY_PASSWORD = "somepass"
46CAPATH = data_file("capath")
47BYTES_CAPATH = CAPATH.encode(sys.getfilesystemencoding())
48CAFILE_NEURONIO = data_file("capath", "4e1295a3.0")
49CAFILE_CACERT = data_file("capath", "5ed36f99.0")
50
51
52# empty CRL
53CRLFILE = data_file("revocation.crl")
54
55# Two keys and certs signed by the same CA (for SNI tests)
56SIGNED_CERTFILE = data_file("keycert3.pem")
57SIGNED_CERTFILE2 = data_file("keycert4.pem")
58SIGNING_CA = data_file("pycacert.pem")
59
60SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
61
62EMPTYCERT = data_file("nullcert.pem")
63BADCERT = data_file("badcert.pem")
64WRONGCERT = data_file("XXXnonexisting.pem")
65BADKEY = data_file("badkey.pem")
66NOKIACERT = data_file("nokia.pem")
67NULLBYTECERT = data_file("nullbytecert.pem")
68
69DHFILE = data_file("dh512.pem")
70BYTES_DHFILE = DHFILE.encode(sys.getfilesystemencoding())
71
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000072
Neal Norwitz3e533c22007-08-27 01:03:18 +000073def handle_error(prefix):
74 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Benjamin Petersondaeb9252014-08-20 14:14:50 -050075 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +000076 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000077
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000078
79class BasicTests(unittest.TestCase):
80
Antoine Pitrou3945c862010-04-28 21:11:01 +000081 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000082 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000083 try:
84 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
85 except IOError, e:
86 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
87 pass
88 else:
89 raise
90 try:
91 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
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
Benjamin Peterson2f334562014-10-01 23:53:01 -040097
98
Benjamin Petersondaeb9252014-08-20 14:14:50 -050099def can_clear_options():
100 # 0.9.8m or higher
101 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
102
103def no_sslv2_implies_sslv3_hello():
104 # 0.9.7h or higher
105 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
106
107def have_verify_flags():
108 # 0.9.8 or higher
109 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 8, 0, 15)
110
111def utc_offset(): #NOTE: ignore issues like #1647654
112 # local time = utc time + utc offset
113 if time.daylight and time.localtime().tm_isdst > 0:
114 return -time.altzone # seconds
115 return -time.timezone
116
117def asn1time(cert_time):
118 # Some versions of OpenSSL ignore seconds, see #18207
119 # 0.9.8.i
120 if ssl._OPENSSL_API_VERSION == (0, 9, 8, 9, 15):
121 fmt = "%b %d %H:%M:%S %Y GMT"
122 dt = datetime.datetime.strptime(cert_time, fmt)
123 dt = dt.replace(second=0)
124 cert_time = dt.strftime(fmt)
125 # %d adds leading zero but ASN1_TIME_print() uses leading space
126 if cert_time[4] == "0":
127 cert_time = cert_time[:4] + " " + cert_time[5:]
128
129 return cert_time
Neal Norwitz3e533c22007-08-27 01:03:18 +0000130
Antoine Pitroud75efd92010-08-04 17:38:33 +0000131# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
132def skip_if_broken_ubuntu_ssl(func):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200133 if hasattr(ssl, 'PROTOCOL_SSLv2'):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200134 @functools.wraps(func)
135 def f(*args, **kwargs):
136 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500137 ssl.SSLContext(ssl.PROTOCOL_SSLv2)
138 except ssl.SSLError:
Victor Stinnerb1241f92011-05-10 01:52:03 +0200139 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500140 platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
Victor Stinnerb1241f92011-05-10 01:52:03 +0200141 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
142 return func(*args, **kwargs)
143 return f
144 else:
145 return func
Antoine Pitroud75efd92010-08-04 17:38:33 +0000146
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500147needs_sni = unittest.skipUnless(ssl.HAS_SNI, "SNI support needed for this test")
148
Antoine Pitroud75efd92010-08-04 17:38:33 +0000149
150class BasicSocketTests(unittest.TestCase):
151
Antoine Pitrou3945c862010-04-28 21:11:01 +0000152 def test_constants(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000153 ssl.CERT_NONE
154 ssl.CERT_OPTIONAL
155 ssl.CERT_REQUIRED
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500156 ssl.OP_CIPHER_SERVER_PREFERENCE
157 ssl.OP_SINGLE_DH_USE
158 if ssl.HAS_ECDH:
159 ssl.OP_SINGLE_ECDH_USE
160 if ssl.OPENSSL_VERSION_INFO >= (1, 0):
161 ssl.OP_NO_COMPRESSION
162 self.assertIn(ssl.HAS_SNI, {True, False})
163 self.assertIn(ssl.HAS_ECDH, {True, False})
164
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000165
Antoine Pitrou3945c862010-04-28 21:11:01 +0000166 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000167 v = ssl.RAND_status()
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500168 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000169 sys.stdout.write("\n RAND_status is %d (%s)\n"
170 % (v, (v and "sufficient randomness") or
171 "insufficient randomness"))
Jesus Ceaa8a5b392012-09-11 01:55:04 +0200172 self.assertRaises(TypeError, ssl.RAND_egd, 1)
173 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000174 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000175
Antoine Pitrou3945c862010-04-28 21:11:01 +0000176 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000177 # note that this uses an 'unofficial' function in _ssl.c,
178 # provided solely for this test, to exercise the certificate
179 # parsing code
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500180 p = ssl._ssl._test_decode_cert(CERTFILE)
181 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000182 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500183 self.assertEqual(p['issuer'],
184 ((('countryName', 'XY'),),
185 (('localityName', 'Castle Anthrax'),),
186 (('organizationName', 'Python Software Foundation'),),
187 (('commonName', 'localhost'),))
188 )
189 # Note the next three asserts will fail if the keys are regenerated
190 self.assertEqual(p['notAfter'], asn1time('Oct 5 23:01:56 2020 GMT'))
191 self.assertEqual(p['notBefore'], asn1time('Oct 8 23:01:56 2010 GMT'))
192 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200193 self.assertEqual(p['subject'],
Antoine Pitrou60982912013-02-16 21:39:28 +0100194 ((('countryName', 'XY'),),
195 (('localityName', 'Castle Anthrax'),),
196 (('organizationName', 'Python Software Foundation'),),
197 (('commonName', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200198 )
Antoine Pitrou60982912013-02-16 21:39:28 +0100199 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200200 # Issue #13034: the subjectAltName in some certificates
201 # (notably projects.developer.nokia.com:443) wasn't parsed
202 p = ssl._ssl._test_decode_cert(NOKIACERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500203 if support.verbose:
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200204 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
205 self.assertEqual(p['subjectAltName'],
206 (('DNS', 'projects.developer.nokia.com'),
207 ('DNS', 'projects.forum.nokia.com'))
208 )
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500209 # extra OCSP and AIA fields
210 self.assertEqual(p['OCSP'], ('http://ocsp.verisign.com',))
211 self.assertEqual(p['caIssuers'],
212 ('http://SVRIntl-G3-aia.verisign.com/SVRIntlG3.cer',))
213 self.assertEqual(p['crlDistributionPoints'],
214 ('http://SVRIntl-G3-crl.verisign.com/SVRIntlG3.crl',))
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000215
Christian Heimes88b174c2013-08-17 00:54:47 +0200216 def test_parse_cert_CVE_2013_4238(self):
217 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500218 if support.verbose:
Christian Heimes88b174c2013-08-17 00:54:47 +0200219 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
220 subject = ((('countryName', 'US'),),
221 (('stateOrProvinceName', 'Oregon'),),
222 (('localityName', 'Beaverton'),),
223 (('organizationName', 'Python Software Foundation'),),
224 (('organizationalUnitName', 'Python Core Development'),),
225 (('commonName', 'null.python.org\x00example.org'),),
226 (('emailAddress', 'python-dev@python.org'),))
227 self.assertEqual(p['subject'], subject)
228 self.assertEqual(p['issuer'], subject)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500229 if ssl._OPENSSL_API_VERSION >= (0, 9, 8):
Christian Heimesf869a942013-08-25 14:12:41 +0200230 san = (('DNS', 'altnull.python.org\x00example.com'),
231 ('email', 'null@python.org\x00user@example.org'),
232 ('URI', 'http://null.python.org\x00http://example.org'),
233 ('IP Address', '192.0.2.1'),
234 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
235 else:
236 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
237 san = (('DNS', 'altnull.python.org\x00example.com'),
238 ('email', 'null@python.org\x00user@example.org'),
239 ('URI', 'http://null.python.org\x00http://example.org'),
240 ('IP Address', '192.0.2.1'),
241 ('IP Address', '<invalid>'))
242
243 self.assertEqual(p['subjectAltName'], san)
Christian Heimes88b174c2013-08-17 00:54:47 +0200244
Antoine Pitrou3945c862010-04-28 21:11:01 +0000245 def test_DER_to_PEM(self):
246 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
247 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000248 d1 = ssl.PEM_cert_to_DER_cert(pem)
249 p2 = ssl.DER_cert_to_PEM_cert(d1)
250 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000251 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000252 if not p2.startswith(ssl.PEM_HEADER + '\n'):
253 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
254 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
255 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000256
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000257 def test_openssl_version(self):
258 n = ssl.OPENSSL_VERSION_NUMBER
259 t = ssl.OPENSSL_VERSION_INFO
260 s = ssl.OPENSSL_VERSION
261 self.assertIsInstance(n, (int, long))
262 self.assertIsInstance(t, tuple)
263 self.assertIsInstance(s, str)
264 # Some sanity checks follow
265 # >= 0.9
266 self.assertGreaterEqual(n, 0x900000)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400267 # < 3.0
268 self.assertLess(n, 0x30000000)
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000269 major, minor, fix, patch, status = t
270 self.assertGreaterEqual(major, 0)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400271 self.assertLess(major, 3)
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000272 self.assertGreaterEqual(minor, 0)
273 self.assertLess(minor, 256)
274 self.assertGreaterEqual(fix, 0)
275 self.assertLess(fix, 256)
276 self.assertGreaterEqual(patch, 0)
277 self.assertLessEqual(patch, 26)
278 self.assertGreaterEqual(status, 0)
279 self.assertLessEqual(status, 15)
Antoine Pitrou4e64d872014-07-21 18:35:01 -0400280 # Version string as returned by {Open,Libre}SSL, the format might change
281 if "LibreSSL" in s:
282 self.assertTrue(s.startswith("LibreSSL {:d}.{:d}".format(major, minor)),
283 (s, t))
284 else:
285 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
286 (s, t))
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000287
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500288 @support.cpython_only
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000289 def test_refcycle(self):
290 # Issue #7943: an SSL object doesn't create reference cycles with
291 # itself.
292 s = socket.socket(socket.AF_INET)
293 ss = ssl.wrap_socket(s)
294 wr = weakref.ref(ss)
295 del ss
296 self.assertEqual(wr(), None)
297
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000298 def test_wrapped_unconnected(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500299 # Methods on an unconnected SSLSocket propagate the original
300 # socket.error raise by the underlying socket object.
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000301 s = socket.socket(socket.AF_INET)
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500302 with closing(ssl.wrap_socket(s)) as ss:
303 self.assertRaises(socket.error, ss.recv, 1)
304 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
305 self.assertRaises(socket.error, ss.recvfrom, 1)
306 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
307 self.assertRaises(socket.error, ss.send, b'x')
308 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
309
310 def test_timeout(self):
311 # Issue #8524: when creating an SSL socket, the timeout of the
312 # original socket should be retained.
313 for timeout in (None, 0.0, 5.0):
314 s = socket.socket(socket.AF_INET)
315 s.settimeout(timeout)
316 with closing(ssl.wrap_socket(s)) as ss:
317 self.assertEqual(timeout, ss.gettimeout())
318
319 def test_errors(self):
320 sock = socket.socket()
321 self.assertRaisesRegexp(ValueError,
322 "certfile must be specified",
323 ssl.wrap_socket, sock, keyfile=CERTFILE)
324 self.assertRaisesRegexp(ValueError,
325 "certfile must be specified for server-side operations",
326 ssl.wrap_socket, sock, server_side=True)
327 self.assertRaisesRegexp(ValueError,
328 "certfile must be specified for server-side operations",
329 ssl.wrap_socket, sock, server_side=True, certfile="")
330 with closing(ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)) as s:
331 self.assertRaisesRegexp(ValueError, "can't connect in server-side mode",
332 s.connect, (HOST, 8080))
333 with self.assertRaises(IOError) as cm:
334 with closing(socket.socket()) as sock:
335 ssl.wrap_socket(sock, certfile=WRONGCERT)
336 self.assertEqual(cm.exception.errno, errno.ENOENT)
337 with self.assertRaises(IOError) as cm:
338 with closing(socket.socket()) as sock:
339 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
340 self.assertEqual(cm.exception.errno, errno.ENOENT)
341 with self.assertRaises(IOError) as cm:
342 with closing(socket.socket()) as sock:
343 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
344 self.assertEqual(cm.exception.errno, errno.ENOENT)
345
346 def test_match_hostname(self):
347 def ok(cert, hostname):
348 ssl.match_hostname(cert, hostname)
349 def fail(cert, hostname):
350 self.assertRaises(ssl.CertificateError,
351 ssl.match_hostname, cert, hostname)
352
353 cert = {'subject': ((('commonName', 'example.com'),),)}
354 ok(cert, 'example.com')
355 ok(cert, 'ExAmple.cOm')
356 fail(cert, 'www.example.com')
357 fail(cert, '.example.com')
358 fail(cert, 'example.org')
359 fail(cert, 'exampleXcom')
360
361 cert = {'subject': ((('commonName', '*.a.com'),),)}
362 ok(cert, 'foo.a.com')
363 fail(cert, 'bar.foo.a.com')
364 fail(cert, 'a.com')
365 fail(cert, 'Xa.com')
366 fail(cert, '.a.com')
367
368 # only match one left-most wildcard
369 cert = {'subject': ((('commonName', 'f*.com'),),)}
370 ok(cert, 'foo.com')
371 ok(cert, 'f.com')
372 fail(cert, 'bar.com')
373 fail(cert, 'foo.a.com')
374 fail(cert, 'bar.foo.com')
375
376 # NULL bytes are bad, CVE-2013-4073
377 cert = {'subject': ((('commonName',
378 'null.python.org\x00example.org'),),)}
379 ok(cert, 'null.python.org\x00example.org') # or raise an error?
380 fail(cert, 'example.org')
381 fail(cert, 'null.python.org')
382
383 # error cases with wildcards
384 cert = {'subject': ((('commonName', '*.*.a.com'),),)}
385 fail(cert, 'bar.foo.a.com')
386 fail(cert, 'a.com')
387 fail(cert, 'Xa.com')
388 fail(cert, '.a.com')
389
390 cert = {'subject': ((('commonName', 'a.*.com'),),)}
391 fail(cert, 'a.foo.com')
392 fail(cert, 'a..com')
393 fail(cert, 'a.com')
394
395 # wildcard doesn't match IDNA prefix 'xn--'
396 idna = u'püthon.python.org'.encode("idna").decode("ascii")
397 cert = {'subject': ((('commonName', idna),),)}
398 ok(cert, idna)
399 cert = {'subject': ((('commonName', 'x*.python.org'),),)}
400 fail(cert, idna)
401 cert = {'subject': ((('commonName', 'xn--p*.python.org'),),)}
402 fail(cert, idna)
403
404 # wildcard in first fragment and IDNA A-labels in sequent fragments
405 # are supported.
406 idna = u'www*.pythön.org'.encode("idna").decode("ascii")
407 cert = {'subject': ((('commonName', idna),),)}
408 ok(cert, u'www.pythön.org'.encode("idna").decode("ascii"))
409 ok(cert, u'www1.pythön.org'.encode("idna").decode("ascii"))
410 fail(cert, u'ftp.pythön.org'.encode("idna").decode("ascii"))
411 fail(cert, u'pythön.org'.encode("idna").decode("ascii"))
412
413 # Slightly fake real-world example
414 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
415 'subject': ((('commonName', 'linuxfrz.org'),),),
416 'subjectAltName': (('DNS', 'linuxfr.org'),
417 ('DNS', 'linuxfr.com'),
418 ('othername', '<unsupported>'))}
419 ok(cert, 'linuxfr.org')
420 ok(cert, 'linuxfr.com')
421 # Not a "DNS" entry
422 fail(cert, '<unsupported>')
423 # When there is a subjectAltName, commonName isn't used
424 fail(cert, 'linuxfrz.org')
425
426 # A pristine real-world example
427 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
428 'subject': ((('countryName', 'US'),),
429 (('stateOrProvinceName', 'California'),),
430 (('localityName', 'Mountain View'),),
431 (('organizationName', 'Google Inc'),),
432 (('commonName', 'mail.google.com'),))}
433 ok(cert, 'mail.google.com')
434 fail(cert, 'gmail.com')
435 # Only commonName is considered
436 fail(cert, 'California')
437
438 # Neither commonName nor subjectAltName
439 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
440 'subject': ((('countryName', 'US'),),
441 (('stateOrProvinceName', 'California'),),
442 (('localityName', 'Mountain View'),),
443 (('organizationName', 'Google Inc'),))}
444 fail(cert, 'mail.google.com')
445
446 # No DNS entry in subjectAltName but a commonName
447 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
448 'subject': ((('countryName', 'US'),),
449 (('stateOrProvinceName', 'California'),),
450 (('localityName', 'Mountain View'),),
451 (('commonName', 'mail.google.com'),)),
452 'subjectAltName': (('othername', 'blabla'), )}
453 ok(cert, 'mail.google.com')
454
455 # No DNS entry subjectAltName and no commonName
456 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
457 'subject': ((('countryName', 'US'),),
458 (('stateOrProvinceName', 'California'),),
459 (('localityName', 'Mountain View'),),
460 (('organizationName', 'Google Inc'),)),
461 'subjectAltName': (('othername', 'blabla'),)}
462 fail(cert, 'google.com')
463
464 # Empty cert / no cert
465 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
466 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
467
468 # Issue #17980: avoid denials of service by refusing more than one
469 # wildcard per fragment.
470 cert = {'subject': ((('commonName', 'a*b.com'),),)}
471 ok(cert, 'axxb.com')
472 cert = {'subject': ((('commonName', 'a*b.co*'),),)}
473 fail(cert, 'axxb.com')
474 cert = {'subject': ((('commonName', 'a*b*.com'),),)}
475 with self.assertRaises(ssl.CertificateError) as cm:
476 ssl.match_hostname(cert, 'axxbxxc.com')
477 self.assertIn("too many wildcards", str(cm.exception))
478
479 def test_server_side(self):
480 # server_hostname doesn't work for server sockets
481 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
482 with closing(socket.socket()) as sock:
483 self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
484 server_hostname="some.hostname")
485
486 def test_unknown_channel_binding(self):
487 # should raise ValueError for unknown type
488 s = socket.socket(socket.AF_INET)
489 with closing(ssl.wrap_socket(s)) as ss:
490 with self.assertRaises(ValueError):
491 ss.get_channel_binding("unknown-type")
492
493 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
494 "'tls-unique' channel binding not available")
495 def test_tls_unique_channel_binding(self):
496 # unconnected should return None for known type
497 s = socket.socket(socket.AF_INET)
498 with closing(ssl.wrap_socket(s)) as ss:
499 self.assertIsNone(ss.get_channel_binding("tls-unique"))
500 # the same for server-side
501 s = socket.socket(socket.AF_INET)
502 with closing(ssl.wrap_socket(s, server_side=True, certfile=CERTFILE)) as ss:
503 self.assertIsNone(ss.get_channel_binding("tls-unique"))
504
505 def test_get_default_verify_paths(self):
506 paths = ssl.get_default_verify_paths()
507 self.assertEqual(len(paths), 6)
508 self.assertIsInstance(paths, ssl.DefaultVerifyPaths)
509
510 with support.EnvironmentVarGuard() as env:
511 env["SSL_CERT_DIR"] = CAPATH
512 env["SSL_CERT_FILE"] = CERTFILE
513 paths = ssl.get_default_verify_paths()
514 self.assertEqual(paths.cafile, CERTFILE)
515 self.assertEqual(paths.capath, CAPATH)
516
517 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
518 def test_enum_certificates(self):
519 self.assertTrue(ssl.enum_certificates("CA"))
520 self.assertTrue(ssl.enum_certificates("ROOT"))
521
522 self.assertRaises(TypeError, ssl.enum_certificates)
523 self.assertRaises(WindowsError, ssl.enum_certificates, "")
524
525 trust_oids = set()
526 for storename in ("CA", "ROOT"):
527 store = ssl.enum_certificates(storename)
528 self.assertIsInstance(store, list)
529 for element in store:
530 self.assertIsInstance(element, tuple)
531 self.assertEqual(len(element), 3)
532 cert, enc, trust = element
533 self.assertIsInstance(cert, bytes)
534 self.assertIn(enc, {"x509_asn", "pkcs_7_asn"})
535 self.assertIsInstance(trust, (set, bool))
536 if isinstance(trust, set):
537 trust_oids.update(trust)
538
539 serverAuth = "1.3.6.1.5.5.7.3.1"
540 self.assertIn(serverAuth, trust_oids)
541
542 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
543 def test_enum_crls(self):
544 self.assertTrue(ssl.enum_crls("CA"))
545 self.assertRaises(TypeError, ssl.enum_crls)
546 self.assertRaises(WindowsError, ssl.enum_crls, "")
547
548 crls = ssl.enum_crls("CA")
549 self.assertIsInstance(crls, list)
550 for element in crls:
551 self.assertIsInstance(element, tuple)
552 self.assertEqual(len(element), 2)
553 self.assertIsInstance(element[0], bytes)
554 self.assertIn(element[1], {"x509_asn", "pkcs_7_asn"})
555
556
557 def test_asn1object(self):
558 expected = (129, 'serverAuth', 'TLS Web Server Authentication',
559 '1.3.6.1.5.5.7.3.1')
560
561 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
562 self.assertEqual(val, expected)
563 self.assertEqual(val.nid, 129)
564 self.assertEqual(val.shortname, 'serverAuth')
565 self.assertEqual(val.longname, 'TLS Web Server Authentication')
566 self.assertEqual(val.oid, '1.3.6.1.5.5.7.3.1')
567 self.assertIsInstance(val, ssl._ASN1Object)
568 self.assertRaises(ValueError, ssl._ASN1Object, 'serverAuth')
569
570 val = ssl._ASN1Object.fromnid(129)
571 self.assertEqual(val, expected)
572 self.assertIsInstance(val, ssl._ASN1Object)
573 self.assertRaises(ValueError, ssl._ASN1Object.fromnid, -1)
574 with self.assertRaisesRegexp(ValueError, "unknown NID 100000"):
575 ssl._ASN1Object.fromnid(100000)
576 for i in range(1000):
577 try:
578 obj = ssl._ASN1Object.fromnid(i)
579 except ValueError:
580 pass
581 else:
582 self.assertIsInstance(obj.nid, int)
583 self.assertIsInstance(obj.shortname, str)
584 self.assertIsInstance(obj.longname, str)
585 self.assertIsInstance(obj.oid, (str, type(None)))
586
587 val = ssl._ASN1Object.fromname('TLS Web Server Authentication')
588 self.assertEqual(val, expected)
589 self.assertIsInstance(val, ssl._ASN1Object)
590 self.assertEqual(ssl._ASN1Object.fromname('serverAuth'), expected)
591 self.assertEqual(ssl._ASN1Object.fromname('1.3.6.1.5.5.7.3.1'),
592 expected)
593 with self.assertRaisesRegexp(ValueError, "unknown object 'serverauth'"):
594 ssl._ASN1Object.fromname('serverauth')
595
596 def test_purpose_enum(self):
597 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.1')
598 self.assertIsInstance(ssl.Purpose.SERVER_AUTH, ssl._ASN1Object)
599 self.assertEqual(ssl.Purpose.SERVER_AUTH, val)
600 self.assertEqual(ssl.Purpose.SERVER_AUTH.nid, 129)
601 self.assertEqual(ssl.Purpose.SERVER_AUTH.shortname, 'serverAuth')
602 self.assertEqual(ssl.Purpose.SERVER_AUTH.oid,
603 '1.3.6.1.5.5.7.3.1')
604
605 val = ssl._ASN1Object('1.3.6.1.5.5.7.3.2')
606 self.assertIsInstance(ssl.Purpose.CLIENT_AUTH, ssl._ASN1Object)
607 self.assertEqual(ssl.Purpose.CLIENT_AUTH, val)
608 self.assertEqual(ssl.Purpose.CLIENT_AUTH.nid, 130)
609 self.assertEqual(ssl.Purpose.CLIENT_AUTH.shortname, 'clientAuth')
610 self.assertEqual(ssl.Purpose.CLIENT_AUTH.oid,
611 '1.3.6.1.5.5.7.3.2')
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000612
Antoine Pitrou63cc99d2013-12-28 17:26:33 +0100613 def test_unsupported_dtls(self):
614 s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
615 self.addCleanup(s.close)
616 with self.assertRaises(NotImplementedError) as cx:
617 ssl.wrap_socket(s, cert_reqs=ssl.CERT_NONE)
618 self.assertEqual(str(cx.exception), "only stream sockets are supported")
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500619 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
620 with self.assertRaises(NotImplementedError) as cx:
621 ctx.wrap_socket(s)
622 self.assertEqual(str(cx.exception), "only stream sockets are supported")
623
624 def cert_time_ok(self, timestring, timestamp):
625 self.assertEqual(ssl.cert_time_to_seconds(timestring), timestamp)
626
627 def cert_time_fail(self, timestring):
628 with self.assertRaises(ValueError):
629 ssl.cert_time_to_seconds(timestring)
630
631 @unittest.skipUnless(utc_offset(),
632 'local time needs to be different from UTC')
633 def test_cert_time_to_seconds_timezone(self):
634 # Issue #19940: ssl.cert_time_to_seconds() returns wrong
635 # results if local timezone is not UTC
636 self.cert_time_ok("May 9 00:00:00 2007 GMT", 1178668800.0)
637 self.cert_time_ok("Jan 5 09:34:43 2018 GMT", 1515144883.0)
638
639 def test_cert_time_to_seconds(self):
640 timestring = "Jan 5 09:34:43 2018 GMT"
641 ts = 1515144883.0
642 self.cert_time_ok(timestring, ts)
643 # accept keyword parameter, assert its name
644 self.assertEqual(ssl.cert_time_to_seconds(cert_time=timestring), ts)
645 # accept both %e and %d (space or zero generated by strftime)
646 self.cert_time_ok("Jan 05 09:34:43 2018 GMT", ts)
647 # case-insensitive
648 self.cert_time_ok("JaN 5 09:34:43 2018 GmT", ts)
649 self.cert_time_fail("Jan 5 09:34 2018 GMT") # no seconds
650 self.cert_time_fail("Jan 5 09:34:43 2018") # no GMT
651 self.cert_time_fail("Jan 5 09:34:43 2018 UTC") # not GMT timezone
652 self.cert_time_fail("Jan 35 09:34:43 2018 GMT") # invalid day
653 self.cert_time_fail("Jon 5 09:34:43 2018 GMT") # invalid month
654 self.cert_time_fail("Jan 5 24:00:00 2018 GMT") # invalid hour
655 self.cert_time_fail("Jan 5 09:60:43 2018 GMT") # invalid minute
656
657 newyear_ts = 1230768000.0
658 # leap seconds
659 self.cert_time_ok("Dec 31 23:59:60 2008 GMT", newyear_ts)
660 # same timestamp
661 self.cert_time_ok("Jan 1 00:00:00 2009 GMT", newyear_ts)
662
663 self.cert_time_ok("Jan 5 09:34:59 2018 GMT", 1515144899)
664 # allow 60th second (even if it is not a leap second)
665 self.cert_time_ok("Jan 5 09:34:60 2018 GMT", 1515144900)
666 # allow 2nd leap second for compatibility with time.strptime()
667 self.cert_time_ok("Jan 5 09:34:61 2018 GMT", 1515144901)
668 self.cert_time_fail("Jan 5 09:34:62 2018 GMT") # invalid seconds
669
670 # no special treatement for the special value:
671 # 99991231235959Z (rfc 5280)
672 self.cert_time_ok("Dec 31 23:59:59 9999 GMT", 253402300799.0)
673
674 @support.run_with_locale('LC_ALL', '')
675 def test_cert_time_to_seconds_locale(self):
676 # `cert_time_to_seconds()` should be locale independent
677
678 def local_february_name():
679 return time.strftime('%b', (1, 2, 3, 4, 5, 6, 0, 0, 0))
680
681 if local_february_name().lower() == 'feb':
682 self.skipTest("locale-specific month name needs to be "
683 "different from C locale")
684
685 # locale-independent
686 self.cert_time_ok("Feb 9 00:00:00 2007 GMT", 1170979200.0)
687 self.cert_time_fail(local_february_name() + " 9 00:00:00 2007 GMT")
688
689
690class ContextTests(unittest.TestCase):
691
692 @skip_if_broken_ubuntu_ssl
693 def test_constructor(self):
694 for protocol in PROTOCOLS:
695 ssl.SSLContext(protocol)
696 self.assertRaises(TypeError, ssl.SSLContext)
697 self.assertRaises(ValueError, ssl.SSLContext, -1)
698 self.assertRaises(ValueError, ssl.SSLContext, 42)
699
700 @skip_if_broken_ubuntu_ssl
701 def test_protocol(self):
702 for proto in PROTOCOLS:
703 ctx = ssl.SSLContext(proto)
704 self.assertEqual(ctx.protocol, proto)
705
706 def test_ciphers(self):
707 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
708 ctx.set_ciphers("ALL")
709 ctx.set_ciphers("DEFAULT")
710 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
711 ctx.set_ciphers("^$:,;?*'dorothyx")
712
713 @skip_if_broken_ubuntu_ssl
714 def test_options(self):
715 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
716 # OP_ALL | OP_NO_SSLv2 is the default value
717 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
718 ctx.options)
719 ctx.options |= ssl.OP_NO_SSLv3
720 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
721 ctx.options)
722 if can_clear_options():
723 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
724 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
725 ctx.options)
726 ctx.options = 0
727 self.assertEqual(0, ctx.options)
728 else:
729 with self.assertRaises(ValueError):
730 ctx.options = 0
731
732 def test_verify_mode(self):
733 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
734 # Default value
735 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
736 ctx.verify_mode = ssl.CERT_OPTIONAL
737 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
738 ctx.verify_mode = ssl.CERT_REQUIRED
739 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
740 ctx.verify_mode = ssl.CERT_NONE
741 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
742 with self.assertRaises(TypeError):
743 ctx.verify_mode = None
744 with self.assertRaises(ValueError):
745 ctx.verify_mode = 42
746
747 @unittest.skipUnless(have_verify_flags(),
748 "verify_flags need OpenSSL > 0.9.8")
749 def test_verify_flags(self):
750 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
751 # default value by OpenSSL
752 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
753 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF
754 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_LEAF)
755 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_CHAIN
756 self.assertEqual(ctx.verify_flags, ssl.VERIFY_CRL_CHECK_CHAIN)
757 ctx.verify_flags = ssl.VERIFY_DEFAULT
758 self.assertEqual(ctx.verify_flags, ssl.VERIFY_DEFAULT)
759 # supports any value
760 ctx.verify_flags = ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT
761 self.assertEqual(ctx.verify_flags,
762 ssl.VERIFY_CRL_CHECK_LEAF | ssl.VERIFY_X509_STRICT)
763 with self.assertRaises(TypeError):
764 ctx.verify_flags = None
765
766 def test_load_cert_chain(self):
767 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
768 # Combined key and cert in a single file
769 ctx.load_cert_chain(CERTFILE)
770 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
771 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
772 with self.assertRaises(IOError) as cm:
773 ctx.load_cert_chain(WRONGCERT)
774 self.assertEqual(cm.exception.errno, errno.ENOENT)
775 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
776 ctx.load_cert_chain(BADCERT)
777 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
778 ctx.load_cert_chain(EMPTYCERT)
779 # Separate key and cert
780 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
781 ctx.load_cert_chain(ONLYCERT, ONLYKEY)
782 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
783 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
784 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
785 ctx.load_cert_chain(ONLYCERT)
786 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
787 ctx.load_cert_chain(ONLYKEY)
788 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
789 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
790 # Mismatching key and cert
791 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
792 with self.assertRaisesRegexp(ssl.SSLError, "key values mismatch"):
793 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
794 # Password protected key and cert
795 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
796 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
797 ctx.load_cert_chain(CERTFILE_PROTECTED,
798 password=bytearray(KEY_PASSWORD.encode()))
799 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
800 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
801 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
802 bytearray(KEY_PASSWORD.encode()))
803 with self.assertRaisesRegexp(TypeError, "should be a string"):
804 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
805 with self.assertRaises(ssl.SSLError):
806 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
807 with self.assertRaisesRegexp(ValueError, "cannot be longer"):
808 # openssl has a fixed limit on the password buffer.
809 # PEM_BUFSIZE is generally set to 1kb.
810 # Return a string larger than this.
811 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
812 # Password callback
813 def getpass_unicode():
814 return KEY_PASSWORD
815 def getpass_bytes():
816 return KEY_PASSWORD.encode()
817 def getpass_bytearray():
818 return bytearray(KEY_PASSWORD.encode())
819 def getpass_badpass():
820 return "badpass"
821 def getpass_huge():
822 return b'a' * (1024 * 1024)
823 def getpass_bad_type():
824 return 9
825 def getpass_exception():
826 raise Exception('getpass error')
827 class GetPassCallable:
828 def __call__(self):
829 return KEY_PASSWORD
830 def getpass(self):
831 return KEY_PASSWORD
832 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
833 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
834 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
835 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
836 ctx.load_cert_chain(CERTFILE_PROTECTED,
837 password=GetPassCallable().getpass)
838 with self.assertRaises(ssl.SSLError):
839 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
840 with self.assertRaisesRegexp(ValueError, "cannot be longer"):
841 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
842 with self.assertRaisesRegexp(TypeError, "must return a string"):
843 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
844 with self.assertRaisesRegexp(Exception, "getpass error"):
845 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
846 # Make sure the password function isn't called if it isn't needed
847 ctx.load_cert_chain(CERTFILE, password=getpass_exception)
848
849 def test_load_verify_locations(self):
850 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
851 ctx.load_verify_locations(CERTFILE)
852 ctx.load_verify_locations(cafile=CERTFILE, capath=None)
853 ctx.load_verify_locations(BYTES_CERTFILE)
854 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
Benjamin Peterson876473e2014-08-28 09:33:21 -0400855 ctx.load_verify_locations(cafile=BYTES_CERTFILE.decode('utf-8'))
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500856 self.assertRaises(TypeError, ctx.load_verify_locations)
857 self.assertRaises(TypeError, ctx.load_verify_locations, None, None, None)
858 with self.assertRaises(IOError) as cm:
859 ctx.load_verify_locations(WRONGCERT)
860 self.assertEqual(cm.exception.errno, errno.ENOENT)
Benjamin Peterson876473e2014-08-28 09:33:21 -0400861 with self.assertRaises(IOError):
862 ctx.load_verify_locations(u'')
Benjamin Petersondaeb9252014-08-20 14:14:50 -0500863 with self.assertRaisesRegexp(ssl.SSLError, "PEM lib"):
864 ctx.load_verify_locations(BADCERT)
865 ctx.load_verify_locations(CERTFILE, CAPATH)
866 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
867
868 # Issue #10989: crash if the second argument type is invalid
869 self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
870
871 def test_load_verify_cadata(self):
872 # test cadata
873 with open(CAFILE_CACERT) as f:
874 cacert_pem = f.read().decode("ascii")
875 cacert_der = ssl.PEM_cert_to_DER_cert(cacert_pem)
876 with open(CAFILE_NEURONIO) as f:
877 neuronio_pem = f.read().decode("ascii")
878 neuronio_der = ssl.PEM_cert_to_DER_cert(neuronio_pem)
879
880 # test PEM
881 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
882 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 0)
883 ctx.load_verify_locations(cadata=cacert_pem)
884 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 1)
885 ctx.load_verify_locations(cadata=neuronio_pem)
886 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
887 # cert already in hash table
888 ctx.load_verify_locations(cadata=neuronio_pem)
889 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
890
891 # combined
892 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
893 combined = "\n".join((cacert_pem, neuronio_pem))
894 ctx.load_verify_locations(cadata=combined)
895 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
896
897 # with junk around the certs
898 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
899 combined = ["head", cacert_pem, "other", neuronio_pem, "again",
900 neuronio_pem, "tail"]
901 ctx.load_verify_locations(cadata="\n".join(combined))
902 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
903
904 # test DER
905 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
906 ctx.load_verify_locations(cadata=cacert_der)
907 ctx.load_verify_locations(cadata=neuronio_der)
908 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
909 # cert already in hash table
910 ctx.load_verify_locations(cadata=cacert_der)
911 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
912
913 # combined
914 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
915 combined = b"".join((cacert_der, neuronio_der))
916 ctx.load_verify_locations(cadata=combined)
917 self.assertEqual(ctx.cert_store_stats()["x509_ca"], 2)
918
919 # error cases
920 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
921 self.assertRaises(TypeError, ctx.load_verify_locations, cadata=object)
922
923 with self.assertRaisesRegexp(ssl.SSLError, "no start line"):
924 ctx.load_verify_locations(cadata=u"broken")
925 with self.assertRaisesRegexp(ssl.SSLError, "not enough data"):
926 ctx.load_verify_locations(cadata=b"broken")
927
928
929 def test_load_dh_params(self):
930 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
931 ctx.load_dh_params(DHFILE)
932 if os.name != 'nt':
933 ctx.load_dh_params(BYTES_DHFILE)
934 self.assertRaises(TypeError, ctx.load_dh_params)
935 self.assertRaises(TypeError, ctx.load_dh_params, None)
936 with self.assertRaises(IOError) as cm:
937 ctx.load_dh_params(WRONGCERT)
938 self.assertEqual(cm.exception.errno, errno.ENOENT)
939 with self.assertRaises(ssl.SSLError) as cm:
940 ctx.load_dh_params(CERTFILE)
941
942 @skip_if_broken_ubuntu_ssl
943 def test_session_stats(self):
944 for proto in PROTOCOLS:
945 ctx = ssl.SSLContext(proto)
946 self.assertEqual(ctx.session_stats(), {
947 'number': 0,
948 'connect': 0,
949 'connect_good': 0,
950 'connect_renegotiate': 0,
951 'accept': 0,
952 'accept_good': 0,
953 'accept_renegotiate': 0,
954 'hits': 0,
955 'misses': 0,
956 'timeouts': 0,
957 'cache_full': 0,
958 })
959
960 def test_set_default_verify_paths(self):
961 # There's not much we can do to test that it acts as expected,
962 # so just check it doesn't crash or raise an exception.
963 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
964 ctx.set_default_verify_paths()
965
966 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
967 def test_set_ecdh_curve(self):
968 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
969 ctx.set_ecdh_curve("prime256v1")
970 ctx.set_ecdh_curve(b"prime256v1")
971 self.assertRaises(TypeError, ctx.set_ecdh_curve)
972 self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
973 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
974 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
975
976 @needs_sni
977 def test_sni_callback(self):
978 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
979
980 # set_servername_callback expects a callable, or None
981 self.assertRaises(TypeError, ctx.set_servername_callback)
982 self.assertRaises(TypeError, ctx.set_servername_callback, 4)
983 self.assertRaises(TypeError, ctx.set_servername_callback, "")
984 self.assertRaises(TypeError, ctx.set_servername_callback, ctx)
985
986 def dummycallback(sock, servername, ctx):
987 pass
988 ctx.set_servername_callback(None)
989 ctx.set_servername_callback(dummycallback)
990
991 @needs_sni
992 def test_sni_callback_refcycle(self):
993 # Reference cycles through the servername callback are detected
994 # and cleared.
995 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
996 def dummycallback(sock, servername, ctx, cycle=ctx):
997 pass
998 ctx.set_servername_callback(dummycallback)
999 wr = weakref.ref(ctx)
1000 del ctx, dummycallback
1001 gc.collect()
1002 self.assertIs(wr(), None)
1003
1004 def test_cert_store_stats(self):
1005 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1006 self.assertEqual(ctx.cert_store_stats(),
1007 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1008 ctx.load_cert_chain(CERTFILE)
1009 self.assertEqual(ctx.cert_store_stats(),
1010 {'x509_ca': 0, 'crl': 0, 'x509': 0})
1011 ctx.load_verify_locations(CERTFILE)
1012 self.assertEqual(ctx.cert_store_stats(),
1013 {'x509_ca': 0, 'crl': 0, 'x509': 1})
1014 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
1015 self.assertEqual(ctx.cert_store_stats(),
1016 {'x509_ca': 1, 'crl': 0, 'x509': 2})
1017
1018 def test_get_ca_certs(self):
1019 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1020 self.assertEqual(ctx.get_ca_certs(), [])
1021 # CERTFILE is not flagged as X509v3 Basic Constraints: CA:TRUE
1022 ctx.load_verify_locations(CERTFILE)
1023 self.assertEqual(ctx.get_ca_certs(), [])
1024 # but SVN_PYTHON_ORG_ROOT_CERT is a CA cert
1025 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
1026 self.assertEqual(ctx.get_ca_certs(),
1027 [{'issuer': ((('organizationName', 'Root CA'),),
1028 (('organizationalUnitName', 'http://www.cacert.org'),),
1029 (('commonName', 'CA Cert Signing Authority'),),
1030 (('emailAddress', 'support@cacert.org'),)),
1031 'notAfter': asn1time('Mar 29 12:29:49 2033 GMT'),
1032 'notBefore': asn1time('Mar 30 12:29:49 2003 GMT'),
1033 'serialNumber': '00',
1034 'crlDistributionPoints': ('https://www.cacert.org/revoke.crl',),
1035 'subject': ((('organizationName', 'Root CA'),),
1036 (('organizationalUnitName', 'http://www.cacert.org'),),
1037 (('commonName', 'CA Cert Signing Authority'),),
1038 (('emailAddress', 'support@cacert.org'),)),
1039 'version': 3}])
1040
1041 with open(SVN_PYTHON_ORG_ROOT_CERT) as f:
1042 pem = f.read()
1043 der = ssl.PEM_cert_to_DER_cert(pem)
1044 self.assertEqual(ctx.get_ca_certs(True), [der])
1045
1046 def test_load_default_certs(self):
1047 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1048 ctx.load_default_certs()
1049
1050 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1051 ctx.load_default_certs(ssl.Purpose.SERVER_AUTH)
1052 ctx.load_default_certs()
1053
1054 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1055 ctx.load_default_certs(ssl.Purpose.CLIENT_AUTH)
1056
1057 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1058 self.assertRaises(TypeError, ctx.load_default_certs, None)
1059 self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
1060
Benjamin Petersona02ae252014-10-03 18:17:15 -04001061 @unittest.skipIf(sys.platform == "win32", "not-Windows specific")
Benjamin Peterson0b30a2b2014-10-03 17:27:05 -04001062 def test_load_default_certs_env(self):
1063 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1064 with support.EnvironmentVarGuard() as env:
1065 env["SSL_CERT_DIR"] = CAPATH
1066 env["SSL_CERT_FILE"] = CERTFILE
1067 ctx.load_default_certs()
1068 self.assertEqual(ctx.cert_store_stats(), {"crl": 0, "x509": 1, "x509_ca": 0})
1069
Benjamin Petersona02ae252014-10-03 18:17:15 -04001070 @unittest.skipUnless(sys.platform == "win32", "Windows specific")
1071 def test_load_default_certs_env_windows(self):
1072 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1073 ctx.load_default_certs()
1074 stats = ctx.cert_store_stats()
1075
1076 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1077 with support.EnvironmentVarGuard() as env:
1078 env["SSL_CERT_DIR"] = CAPATH
1079 env["SSL_CERT_FILE"] = CERTFILE
1080 ctx.load_default_certs()
1081 stats["x509"] += 1
1082 self.assertEqual(ctx.cert_store_stats(), stats)
1083
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001084 def test_create_default_context(self):
1085 ctx = ssl.create_default_context()
1086 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1087 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1088 self.assertTrue(ctx.check_hostname)
1089 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1090 self.assertEqual(
1091 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1092 getattr(ssl, "OP_NO_COMPRESSION", 0),
1093 )
1094
1095 with open(SIGNING_CA) as f:
1096 cadata = f.read().decode("ascii")
1097 ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
1098 cadata=cadata)
1099 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1100 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1101 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1102 self.assertEqual(
1103 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1104 getattr(ssl, "OP_NO_COMPRESSION", 0),
1105 )
1106
1107 ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
1108 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1109 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1110 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1111 self.assertEqual(
1112 ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0),
1113 getattr(ssl, "OP_NO_COMPRESSION", 0),
1114 )
1115 self.assertEqual(
1116 ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0),
1117 getattr(ssl, "OP_SINGLE_DH_USE", 0),
1118 )
1119 self.assertEqual(
1120 ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1121 getattr(ssl, "OP_SINGLE_ECDH_USE", 0),
1122 )
1123
1124 def test__create_stdlib_context(self):
1125 ctx = ssl._create_stdlib_context()
1126 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1127 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1128 self.assertFalse(ctx.check_hostname)
1129 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1130
1131 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1)
1132 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1133 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1134 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1135
1136 ctx = ssl._create_stdlib_context(ssl.PROTOCOL_TLSv1,
1137 cert_reqs=ssl.CERT_REQUIRED,
1138 check_hostname=True)
1139 self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
1140 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
1141 self.assertTrue(ctx.check_hostname)
1142 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1143
1144 ctx = ssl._create_stdlib_context(purpose=ssl.Purpose.CLIENT_AUTH)
1145 self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23)
1146 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
1147 self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
1148
1149 def test_check_hostname(self):
1150 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1151 self.assertFalse(ctx.check_hostname)
1152
1153 # Requires CERT_REQUIRED or CERT_OPTIONAL
1154 with self.assertRaises(ValueError):
1155 ctx.check_hostname = True
1156 ctx.verify_mode = ssl.CERT_REQUIRED
1157 self.assertFalse(ctx.check_hostname)
1158 ctx.check_hostname = True
1159 self.assertTrue(ctx.check_hostname)
1160
1161 ctx.verify_mode = ssl.CERT_OPTIONAL
1162 ctx.check_hostname = True
1163 self.assertTrue(ctx.check_hostname)
1164
1165 # Cannot set CERT_NONE with check_hostname enabled
1166 with self.assertRaises(ValueError):
1167 ctx.verify_mode = ssl.CERT_NONE
1168 ctx.check_hostname = False
1169 self.assertFalse(ctx.check_hostname)
1170
1171
1172class SSLErrorTests(unittest.TestCase):
1173
1174 def test_str(self):
1175 # The str() of a SSLError doesn't include the errno
1176 e = ssl.SSLError(1, "foo")
1177 self.assertEqual(str(e), "foo")
1178 self.assertEqual(e.errno, 1)
1179 # Same for a subclass
1180 e = ssl.SSLZeroReturnError(1, "foo")
1181 self.assertEqual(str(e), "foo")
1182 self.assertEqual(e.errno, 1)
1183
1184 def test_lib_reason(self):
1185 # Test the library and reason attributes
1186 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1187 with self.assertRaises(ssl.SSLError) as cm:
1188 ctx.load_dh_params(CERTFILE)
1189 self.assertEqual(cm.exception.library, 'PEM')
1190 self.assertEqual(cm.exception.reason, 'NO_START_LINE')
1191 s = str(cm.exception)
1192 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s)
1193
1194 def test_subclass(self):
1195 # Check that the appropriate SSLError subclass is raised
1196 # (this only tests one of them)
1197 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1198 with closing(socket.socket()) as s:
1199 s.bind(("127.0.0.1", 0))
1200 s.listen(5)
1201 c = socket.socket()
1202 c.connect(s.getsockname())
1203 c.setblocking(False)
1204 with closing(ctx.wrap_socket(c, False, do_handshake_on_connect=False)) as c:
1205 with self.assertRaises(ssl.SSLWantReadError) as cm:
1206 c.do_handshake()
1207 s = str(cm.exception)
1208 self.assertTrue(s.startswith("The operation did not complete (read)"), s)
1209 # For compatibility
1210 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ)
Antoine Pitrou63cc99d2013-12-28 17:26:33 +01001211
Antoine Pitrouf9de5342010-04-05 21:35:07 +00001212
Bill Janssen934b16d2008-06-28 22:19:33 +00001213class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +00001214
Antoine Pitrou3945c862010-04-28 21:11:01 +00001215 def test_connect(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001216 with support.transient_internet("svn.python.org"):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001217 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1218 cert_reqs=ssl.CERT_NONE)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001219 try:
1220 s.connect(("svn.python.org", 443))
1221 self.assertEqual({}, s.getpeercert())
1222 finally:
1223 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +00001224
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001225 # this should fail because we have no verification certs
1226 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1227 cert_reqs=ssl.CERT_REQUIRED)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001228 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
1229 s.connect, ("svn.python.org", 443))
1230 s.close()
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001231
1232 # this should succeed because we specify the root cert
1233 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1234 cert_reqs=ssl.CERT_REQUIRED,
1235 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1236 try:
1237 s.connect(("svn.python.org", 443))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001238 self.assertTrue(s.getpeercert())
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001239 finally:
1240 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +00001241
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001242 def test_connect_ex(self):
1243 # Issue #11326: check connect_ex() implementation
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001244 with support.transient_internet("svn.python.org"):
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001245 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1246 cert_reqs=ssl.CERT_REQUIRED,
1247 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1248 try:
1249 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
1250 self.assertTrue(s.getpeercert())
1251 finally:
1252 s.close()
1253
1254 def test_non_blocking_connect_ex(self):
1255 # Issue #11326: non-blocking connect_ex() should allow handshake
1256 # to proceed after the socket gets ready.
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001257 with support.transient_internet("svn.python.org"):
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001258 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1259 cert_reqs=ssl.CERT_REQUIRED,
1260 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
1261 do_handshake_on_connect=False)
1262 try:
1263 s.setblocking(False)
1264 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +00001265 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
1266 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001267 # Wait for connect to finish
1268 select.select([], [s], [], 5.0)
1269 # Non-blocking handshake
1270 while True:
1271 try:
1272 s.do_handshake()
1273 break
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001274 except ssl.SSLWantReadError:
1275 select.select([s], [], [], 5.0)
1276 except ssl.SSLWantWriteError:
1277 select.select([], [s], [], 5.0)
Antoine Pitroud3f6ea12011-02-26 23:35:27 +00001278 # SSL established
1279 self.assertTrue(s.getpeercert())
1280 finally:
1281 s.close()
1282
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001283 def test_timeout_connect_ex(self):
1284 # Issue #12065: on a timeout, connect_ex() should return the original
1285 # errno (mimicking the behaviour of non-SSL sockets).
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001286 with support.transient_internet("svn.python.org"):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001287 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1288 cert_reqs=ssl.CERT_REQUIRED,
1289 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
1290 do_handshake_on_connect=False)
1291 try:
1292 s.settimeout(0.0000001)
1293 rc = s.connect_ex(('svn.python.org', 443))
1294 if rc == 0:
1295 self.skipTest("svn.python.org responded too quickly")
1296 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
1297 finally:
1298 s.close()
1299
1300 def test_connect_ex_error(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001301 with support.transient_internet("svn.python.org"):
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001302 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
1303 cert_reqs=ssl.CERT_REQUIRED,
1304 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
1305 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001306 rc = s.connect_ex(("svn.python.org", 444))
1307 # Issue #19919: Windows machines or VMs hosted on Windows
1308 # machines sometimes return EWOULDBLOCK.
1309 self.assertIn(rc, (errno.ECONNREFUSED, errno.EWOULDBLOCK))
Antoine Pitrou40f12ab2012-12-28 19:03:43 +01001310 finally:
1311 s.close()
1312
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001313 def test_connect_with_context(self):
1314 with support.transient_internet("svn.python.org"):
1315 # Same as test_connect, but with a separately created context
1316 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1317 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1318 s.connect(("svn.python.org", 443))
1319 try:
1320 self.assertEqual({}, s.getpeercert())
1321 finally:
1322 s.close()
1323 # Same with a server hostname
1324 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1325 server_hostname="svn.python.org")
1326 if ssl.HAS_SNI:
1327 s.connect(("svn.python.org", 443))
1328 s.close()
1329 else:
1330 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
1331 # This should fail because we have no verification certs
1332 ctx.verify_mode = ssl.CERT_REQUIRED
1333 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1334 self.assertRaisesRegexp(ssl.SSLError, "certificate verify failed",
1335 s.connect, ("svn.python.org", 443))
1336 s.close()
1337 # This should succeed because we specify the root cert
1338 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
1339 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1340 s.connect(("svn.python.org", 443))
1341 try:
1342 cert = s.getpeercert()
1343 self.assertTrue(cert)
1344 finally:
1345 s.close()
1346
1347 def test_connect_capath(self):
1348 # Verify server certificates using the `capath` argument
1349 # NOTE: the subject hashing algorithm has been changed between
1350 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
1351 # contain both versions of each certificate (same content, different
1352 # filename) for this test to be portable across OpenSSL releases.
1353 with support.transient_internet("svn.python.org"):
1354 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1355 ctx.verify_mode = ssl.CERT_REQUIRED
1356 ctx.load_verify_locations(capath=CAPATH)
1357 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1358 s.connect(("svn.python.org", 443))
1359 try:
1360 cert = s.getpeercert()
1361 self.assertTrue(cert)
1362 finally:
1363 s.close()
1364 # Same with a bytes `capath` argument
1365 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1366 ctx.verify_mode = ssl.CERT_REQUIRED
1367 ctx.load_verify_locations(capath=BYTES_CAPATH)
1368 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1369 s.connect(("svn.python.org", 443))
1370 try:
1371 cert = s.getpeercert()
1372 self.assertTrue(cert)
1373 finally:
1374 s.close()
1375
1376 def test_connect_cadata(self):
1377 with open(CAFILE_CACERT) as f:
1378 pem = f.read().decode('ascii')
1379 der = ssl.PEM_cert_to_DER_cert(pem)
1380 with support.transient_internet("svn.python.org"):
1381 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1382 ctx.verify_mode = ssl.CERT_REQUIRED
1383 ctx.load_verify_locations(cadata=pem)
1384 with closing(ctx.wrap_socket(socket.socket(socket.AF_INET))) as s:
1385 s.connect(("svn.python.org", 443))
1386 cert = s.getpeercert()
1387 self.assertTrue(cert)
1388
1389 # same with DER
1390 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1391 ctx.verify_mode = ssl.CERT_REQUIRED
1392 ctx.load_verify_locations(cadata=der)
1393 with closing(ctx.wrap_socket(socket.socket(socket.AF_INET))) as s:
1394 s.connect(("svn.python.org", 443))
1395 cert = s.getpeercert()
1396 self.assertTrue(cert)
1397
Antoine Pitrou55841ac2010-04-24 10:43:57 +00001398 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
1399 def test_makefile_close(self):
1400 # Issue #5238: creating a file-like object with makefile() shouldn't
1401 # delay closing the underlying "real socket" (here tested with its
1402 # file descriptor, hence skipping the test under Windows).
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001403 with support.transient_internet("svn.python.org"):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001404 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
1405 ss.connect(("svn.python.org", 443))
1406 fd = ss.fileno()
1407 f = ss.makefile()
1408 f.close()
1409 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +00001410 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001411 # Closing the SSL socket should close the fd too
1412 ss.close()
1413 gc.collect()
1414 with self.assertRaises(OSError) as e:
1415 os.read(fd, 0)
1416 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +00001417
Antoine Pitrou3945c862010-04-28 21:11:01 +00001418 def test_non_blocking_handshake(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001419 with support.transient_internet("svn.python.org"):
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001420 s = socket.socket(socket.AF_INET)
1421 s.connect(("svn.python.org", 443))
1422 s.setblocking(False)
1423 s = ssl.wrap_socket(s,
1424 cert_reqs=ssl.CERT_NONE,
1425 do_handshake_on_connect=False)
1426 count = 0
1427 while True:
1428 try:
1429 count += 1
1430 s.do_handshake()
1431 break
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001432 except ssl.SSLWantReadError:
1433 select.select([s], [], [])
1434 except ssl.SSLWantWriteError:
1435 select.select([], [s], [])
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001436 s.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001437 if support.verbose:
Antoine Pitrou4e406d82010-09-09 13:35:44 +00001438 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +00001439
Antoine Pitrou3945c862010-04-28 21:11:01 +00001440 def test_get_server_certificate(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001441 def _test_get_server_certificate(host, port, cert=None):
1442 with support.transient_internet(host):
1443 pem = ssl.get_server_certificate((host, port))
1444 if not pem:
1445 self.fail("No server certificate on %s:%s!" % (host, port))
Bill Janssen296a59d2007-09-16 22:06:00 +00001446
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001447 try:
1448 pem = ssl.get_server_certificate((host, port),
1449 ca_certs=CERTFILE)
1450 except ssl.SSLError as x:
1451 #should fail
1452 if support.verbose:
1453 sys.stdout.write("%s\n" % x)
1454 else:
1455 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
Bill Janssen296a59d2007-09-16 22:06:00 +00001456
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001457 pem = ssl.get_server_certificate((host, port),
1458 ca_certs=cert)
1459 if not pem:
1460 self.fail("No server certificate on %s:%s!" % (host, port))
1461 if support.verbose:
1462 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
1463
1464 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
1465 if support.IPV6_ENABLED:
1466 _test_get_server_certificate('ipv6.google.com', 443)
1467
1468 def test_ciphers(self):
1469 remote = ("svn.python.org", 443)
1470 with support.transient_internet(remote[0]):
1471 with closing(ssl.wrap_socket(socket.socket(socket.AF_INET),
1472 cert_reqs=ssl.CERT_NONE, ciphers="ALL")) as s:
1473 s.connect(remote)
1474 with closing(ssl.wrap_socket(socket.socket(socket.AF_INET),
1475 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")) as s:
1476 s.connect(remote)
1477 # Error checking can happen at instantiation or when connecting
1478 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
1479 with closing(socket.socket(socket.AF_INET)) as sock:
1480 s = ssl.wrap_socket(sock,
1481 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
1482 s.connect(remote)
Bill Janssen296a59d2007-09-16 22:06:00 +00001483
Antoine Pitrouc715a9e2010-04-21 19:28:03 +00001484 def test_algorithms(self):
1485 # Issue #8484: all algorithms should be available when verifying a
1486 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +00001487 # SHA256 was added in OpenSSL 0.9.8
1488 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
1489 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001490 # sha256.tbs-internet.com needs SNI to use the correct certificate
1491 if not ssl.HAS_SNI:
1492 self.skipTest("SNI needed for this test")
1493 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
Antoine Pitroud43245a2011-01-08 10:32:51 +00001494 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +00001495 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001496 with support.transient_internet("sha256.tbs-internet.com"):
1497 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1498 ctx.verify_mode = ssl.CERT_REQUIRED
1499 ctx.load_verify_locations(sha256_cert)
1500 s = ctx.wrap_socket(socket.socket(socket.AF_INET),
1501 server_hostname="sha256.tbs-internet.com")
Antoine Pitrouc715a9e2010-04-21 19:28:03 +00001502 try:
1503 s.connect(remote)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001504 if support.verbose:
Antoine Pitrouc715a9e2010-04-21 19:28:03 +00001505 sys.stdout.write("\nCipher with %r is %r\n" %
1506 (remote, s.cipher()))
1507 sys.stdout.write("Certificate is:\n%s\n" %
1508 pprint.pformat(s.getpeercert()))
1509 finally:
1510 s.close()
1511
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001512 def test_get_ca_certs_capath(self):
1513 # capath certs are loaded on request
1514 with support.transient_internet("svn.python.org"):
1515 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1516 ctx.verify_mode = ssl.CERT_REQUIRED
1517 ctx.load_verify_locations(capath=CAPATH)
1518 self.assertEqual(ctx.get_ca_certs(), [])
1519 s = ctx.wrap_socket(socket.socket(socket.AF_INET))
1520 s.connect(("svn.python.org", 443))
1521 try:
1522 cert = s.getpeercert()
1523 self.assertTrue(cert)
1524 finally:
1525 s.close()
1526 self.assertEqual(len(ctx.get_ca_certs()), 1)
1527
1528 @needs_sni
1529 def test_context_setget(self):
1530 # Check that the context of a connected socket can be replaced.
1531 with support.transient_internet("svn.python.org"):
1532 ctx1 = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1533 ctx2 = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1534 s = socket.socket(socket.AF_INET)
1535 with closing(ctx1.wrap_socket(s)) as ss:
1536 ss.connect(("svn.python.org", 443))
1537 self.assertIs(ss.context, ctx1)
1538 self.assertIs(ss._sslobj.context, ctx1)
1539 ss.context = ctx2
1540 self.assertIs(ss.context, ctx2)
1541 self.assertIs(ss._sslobj.context, ctx2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001542
Bill Janssen98d19da2007-09-10 21:51:02 +00001543try:
1544 import threading
1545except ImportError:
1546 _have_threads = False
1547else:
Bill Janssen98d19da2007-09-10 21:51:02 +00001548 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001549
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001550 from test.ssl_servers import make_https_server
1551
Bill Janssen98d19da2007-09-10 21:51:02 +00001552 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001553
Bill Janssen98d19da2007-09-10 21:51:02 +00001554 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001555
Bill Janssen98d19da2007-09-10 21:51:02 +00001556 """A mildly complicated class, because we want it to work both
1557 with and without the SSL wrapper around the socket connection, so
1558 that we can test the STARTTLS functionality."""
1559
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001560 def __init__(self, server, connsock, addr):
Bill Janssen98d19da2007-09-10 21:51:02 +00001561 self.server = server
1562 self.running = False
1563 self.sock = connsock
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001564 self.addr = addr
Bill Janssen98d19da2007-09-10 21:51:02 +00001565 self.sock.setblocking(1)
1566 self.sslconn = None
1567 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001568 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +00001569
Antoine Pitrou3945c862010-04-28 21:11:01 +00001570 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001571 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001572 self.sslconn = self.server.context.wrap_socket(
1573 self.sock, server_side=True)
1574 self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
1575 except socket.error as e:
1576 # We treat ConnectionResetError as though it were an
1577 # SSLError - OpenSSL on Ubuntu abruptly closes the
1578 # connection when asked to use an unsupported protocol.
1579 #
Antoine Pitroudb187842010-04-27 10:32:58 +00001580 # XXX Various errors can have happened here, for example
1581 # a mismatching protocol version, an invalid certificate,
1582 # or a low-level bug. This should be made more discriminating.
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001583 if not isinstance(e, ssl.SSLError) and e.errno != errno.ECONNRESET:
1584 raise
Antoine Pitroud76088d2012-01-03 22:46:48 +01001585 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +00001586 if self.server.chatty:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001587 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
Antoine Pitroudb187842010-04-27 10:32:58 +00001588 self.running = False
1589 self.server.stop()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001590 self.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001591 return False
Bill Janssen98d19da2007-09-10 21:51:02 +00001592 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001593 if self.server.context.verify_mode == ssl.CERT_REQUIRED:
1594 cert = self.sslconn.getpeercert()
1595 if support.verbose and self.server.chatty:
1596 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
1597 cert_binary = self.sslconn.getpeercert(True)
1598 if support.verbose and self.server.chatty:
1599 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
1600 cipher = self.sslconn.cipher()
1601 if support.verbose and self.server.chatty:
1602 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
1603 sys.stdout.write(" server: selected protocol is now "
1604 + str(self.sslconn.selected_npn_protocol()) + "\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001605 return True
1606
1607 def read(self):
1608 if self.sslconn:
1609 return self.sslconn.read()
1610 else:
1611 return self.sock.recv(1024)
1612
1613 def write(self, bytes):
1614 if self.sslconn:
1615 return self.sslconn.write(bytes)
1616 else:
1617 return self.sock.send(bytes)
1618
1619 def close(self):
1620 if self.sslconn:
1621 self.sslconn.close()
1622 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001623 self.sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001624
Antoine Pitrou3945c862010-04-28 21:11:01 +00001625 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001626 self.running = True
1627 if not self.server.starttls_server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001628 if not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +00001629 return
1630 while self.running:
1631 try:
1632 msg = self.read()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001633 stripped = msg.strip()
1634 if not stripped:
Bill Janssen98d19da2007-09-10 21:51:02 +00001635 # eof, so quit this handler
1636 self.running = False
1637 self.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001638 elif stripped == b'over':
1639 if support.verbose and self.server.connectionchatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001640 sys.stdout.write(" server: client closed connection\n")
1641 self.close()
1642 return
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001643 elif (self.server.starttls_server and
1644 stripped == b'STARTTLS'):
1645 if support.verbose and self.server.connectionchatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001646 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001647 self.write(b"OK\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001648 if not self.wrap_conn():
1649 return
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001650 elif (self.server.starttls_server and self.sslconn
1651 and stripped == b'ENDTLS'):
1652 if support.verbose and self.server.connectionchatty:
Bill Janssen39295c22008-08-12 16:31:21 +00001653 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001654 self.write(b"OK\n")
1655 self.sock = self.sslconn.unwrap()
Bill Janssen39295c22008-08-12 16:31:21 +00001656 self.sslconn = None
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001657 if support.verbose and self.server.connectionchatty:
Bill Janssen39295c22008-08-12 16:31:21 +00001658 sys.stdout.write(" server: connection is now unencrypted...\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001659 elif stripped == b'CB tls-unique':
1660 if support.verbose and self.server.connectionchatty:
1661 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1662 data = self.sslconn.get_channel_binding("tls-unique")
1663 self.write(repr(data).encode("us-ascii") + b"\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001664 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001665 if (support.verbose and
Bill Janssen98d19da2007-09-10 21:51:02 +00001666 self.server.connectionchatty):
1667 ctype = (self.sslconn and "encrypted") or "unencrypted"
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001668 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1669 % (msg, ctype, msg.lower(), ctype))
Bill Janssen98d19da2007-09-10 21:51:02 +00001670 self.write(msg.lower())
1671 except ssl.SSLError:
1672 if self.server.chatty:
1673 handle_error("Test server failure:\n")
1674 self.close()
1675 self.running = False
1676 # normally, we'd just stop here, but for the test
1677 # harness, we want to stop the server
1678 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +00001679
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001680 def __init__(self, certificate=None, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +00001681 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +00001682 chatty=True, connectionchatty=False, starttls_server=False,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001683 npn_protocols=None, ciphers=None, context=None):
1684 if context:
1685 self.context = context
1686 else:
1687 self.context = ssl.SSLContext(ssl_version
1688 if ssl_version is not None
1689 else ssl.PROTOCOL_TLSv1)
1690 self.context.verify_mode = (certreqs if certreqs is not None
1691 else ssl.CERT_NONE)
1692 if cacerts:
1693 self.context.load_verify_locations(cacerts)
1694 if certificate:
1695 self.context.load_cert_chain(certificate)
1696 if npn_protocols:
1697 self.context.set_npn_protocols(npn_protocols)
1698 if ciphers:
1699 self.context.set_ciphers(ciphers)
Bill Janssen98d19da2007-09-10 21:51:02 +00001700 self.chatty = chatty
1701 self.connectionchatty = connectionchatty
1702 self.starttls_server = starttls_server
1703 self.sock = socket.socket()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001704 self.port = support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +00001705 self.flag = None
Bill Janssen98d19da2007-09-10 21:51:02 +00001706 self.active = False
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001707 self.selected_protocols = []
Antoine Pitroud76088d2012-01-03 22:46:48 +01001708 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001709 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001710 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +00001711
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001712 def __enter__(self):
1713 self.start(threading.Event())
1714 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +01001715 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001716
1717 def __exit__(self, *args):
1718 self.stop()
1719 self.join()
1720
Antoine Pitrou3945c862010-04-28 21:11:01 +00001721 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +00001722 self.flag = flag
1723 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001724
Antoine Pitrou3945c862010-04-28 21:11:01 +00001725 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +00001726 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +00001727 self.sock.listen(5)
1728 self.active = True
1729 if self.flag:
1730 # signal an event
1731 self.flag.set()
1732 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001733 try:
Bill Janssen98d19da2007-09-10 21:51:02 +00001734 newconn, connaddr = self.sock.accept()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001735 if support.verbose and self.chatty:
Bill Janssen98d19da2007-09-10 21:51:02 +00001736 sys.stdout.write(' server: new connection from '
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001737 + repr(connaddr) + '\n')
1738 handler = self.ConnectionHandler(self, newconn, connaddr)
Bill Janssen98d19da2007-09-10 21:51:02 +00001739 handler.start()
Antoine Pitrou7a556842012-01-27 17:33:01 +01001740 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +00001741 except socket.timeout:
1742 pass
1743 except KeyboardInterrupt:
1744 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +00001745 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001746
Antoine Pitrou3945c862010-04-28 21:11:01 +00001747 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +00001748 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001749
Bill Janssen934b16d2008-06-28 22:19:33 +00001750 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +00001751
Antoine Pitrou3945c862010-04-28 21:11:01 +00001752 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +00001753
Antoine Pitrou3945c862010-04-28 21:11:01 +00001754 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +00001755
1756 def __init__(self, conn, certfile):
Bill Janssen934b16d2008-06-28 22:19:33 +00001757 self.socket = ssl.wrap_socket(conn, server_side=True,
1758 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +00001759 do_handshake_on_connect=False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001760 asyncore.dispatcher_with_send.__init__(self, self.socket)
Antoine Pitroufc69af12010-04-24 20:04:58 +00001761 self._ssl_accepting = True
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001762 self._do_ssl_handshake()
Bill Janssen934b16d2008-06-28 22:19:33 +00001763
1764 def readable(self):
1765 if isinstance(self.socket, ssl.SSLSocket):
1766 while self.socket.pending() > 0:
1767 self.handle_read_event()
1768 return True
1769
Antoine Pitroufc69af12010-04-24 20:04:58 +00001770 def _do_ssl_handshake(self):
1771 try:
1772 self.socket.do_handshake()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001773 except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1774 return
1775 except ssl.SSLEOFError:
1776 return self.handle_close()
1777 except ssl.SSLError:
Antoine Pitroufc69af12010-04-24 20:04:58 +00001778 raise
1779 except socket.error, err:
1780 if err.args[0] == errno.ECONNABORTED:
1781 return self.handle_close()
1782 else:
1783 self._ssl_accepting = False
1784
Bill Janssen934b16d2008-06-28 22:19:33 +00001785 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +00001786 if self._ssl_accepting:
1787 self._do_ssl_handshake()
1788 else:
1789 data = self.recv(1024)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001790 if support.verbose:
1791 sys.stdout.write(" server: read %s from client\n" % repr(data))
1792 if not data:
1793 self.close()
1794 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001795 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +00001796
1797 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +00001798 self.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001799 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00001800 sys.stdout.write(" server: closed connection %s\n" % self.socket)
1801
1802 def handle_error(self):
1803 raise
1804
1805 def __init__(self, certfile):
1806 self.certfile = certfile
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001807 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1808 self.port = support.bind_port(sock, '')
1809 asyncore.dispatcher.__init__(self, sock)
Bill Janssen934b16d2008-06-28 22:19:33 +00001810 self.listen(5)
1811
1812 def handle_accept(self):
1813 sock_obj, addr = self.accept()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001814 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00001815 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
1816 self.ConnectionHandler(sock_obj, self.certfile)
1817
1818 def handle_error(self):
1819 raise
1820
1821 def __init__(self, certfile):
1822 self.flag = None
1823 self.active = False
1824 self.server = self.EchoServer(certfile)
1825 self.port = self.server.port
1826 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +00001827 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +00001828
1829 def __str__(self):
1830 return "<%s %s>" % (self.__class__.__name__, self.server)
1831
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001832 def __enter__(self):
1833 self.start(threading.Event())
1834 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +01001835 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001836
1837 def __exit__(self, *args):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001838 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001839 sys.stdout.write(" cleanup: stopping server.\n")
1840 self.stop()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001841 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001842 sys.stdout.write(" cleanup: joining server thread.\n")
1843 self.join()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001844 if support.verbose:
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001845 sys.stdout.write(" cleanup: successfully joined.\n")
1846
Antoine Pitrou3945c862010-04-28 21:11:01 +00001847 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +00001848 self.flag = flag
1849 threading.Thread.start(self)
1850
Antoine Pitrou3945c862010-04-28 21:11:01 +00001851 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +00001852 self.active = True
1853 if self.flag:
1854 self.flag.set()
1855 while self.active:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001856 try:
1857 asyncore.loop(1)
1858 except:
1859 pass
Bill Janssen934b16d2008-06-28 22:19:33 +00001860
Antoine Pitrou3945c862010-04-28 21:11:01 +00001861 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +00001862 self.active = False
1863 self.server.close()
1864
Antoine Pitrou3945c862010-04-28 21:11:01 +00001865 def bad_cert_test(certfile):
1866 """
1867 Launch a server with CERT_REQUIRED, and check that trying to
1868 connect to it with the given client certificate fails.
1869 """
Trent Nelsone41b0062008-04-08 23:47:30 +00001870 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001871 certreqs=ssl.CERT_REQUIRED,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001872 cacerts=CERTFILE, chatty=False,
1873 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001874 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001875 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001876 with closing(socket.socket()) as sock:
1877 s = ssl.wrap_socket(sock,
1878 certfile=certfile,
1879 ssl_version=ssl.PROTOCOL_TLSv1)
1880 s.connect((HOST, server.port))
1881 except ssl.SSLError as x:
1882 if support.verbose:
1883 sys.stdout.write("\nSSLError is %s\n" % x.args[1])
1884 except OSError as x:
1885 if support.verbose:
1886 sys.stdout.write("\nOSError is %s\n" % x.args[1])
1887 except OSError as x:
1888 if x.errno != errno.ENOENT:
1889 raise
1890 if support.verbose:
1891 sys.stdout.write("\OSError is %s\n" % str(x))
Bill Janssen98d19da2007-09-10 21:51:02 +00001892 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +00001893 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001894
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001895 def server_params_test(client_context, server_context, indata=b"FOO\n",
1896 chatty=True, connectionchatty=False, sni_name=None):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001897 """
1898 Launch a server, connect a client to it and try various reads
1899 and writes.
1900 """
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001901 stats = {}
1902 server = ThreadedEchoServer(context=server_context,
Bill Janssen98d19da2007-09-10 21:51:02 +00001903 chatty=chatty,
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001904 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001905 with server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001906 with closing(client_context.wrap_socket(socket.socket(),
1907 server_hostname=sni_name)) as s:
1908 s.connect((HOST, server.port))
1909 for arg in [indata, bytearray(indata), memoryview(indata)]:
1910 if connectionchatty:
1911 if support.verbose:
1912 sys.stdout.write(
1913 " client: sending %r...\n" % indata)
1914 s.write(arg)
1915 outdata = s.read()
1916 if connectionchatty:
1917 if support.verbose:
1918 sys.stdout.write(" client: read %r\n" % outdata)
1919 if outdata != indata.lower():
1920 raise AssertionError(
1921 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1922 % (outdata[:20], len(outdata),
1923 indata[:20].lower(), len(indata)))
1924 s.write(b"over\n")
Bill Janssen98d19da2007-09-10 21:51:02 +00001925 if connectionchatty:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001926 if support.verbose:
1927 sys.stdout.write(" client: closing connection.\n")
1928 stats.update({
1929 'compression': s.compression(),
1930 'cipher': s.cipher(),
1931 'peercert': s.getpeercert(),
Alex Gaynore98205d2014-09-04 13:33:22 -07001932 'client_npn_protocol': s.selected_npn_protocol(),
1933 'version': s.version(),
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001934 })
1935 s.close()
1936 stats['server_npn_protocols'] = server.selected_protocols
1937 return stats
Bill Janssen98d19da2007-09-10 21:51:02 +00001938
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001939 def try_protocol_combo(server_protocol, client_protocol, expect_success,
1940 certsreqs=None, server_options=0, client_options=0):
Alex Gaynore98205d2014-09-04 13:33:22 -07001941 """
1942 Try to SSL-connect using *client_protocol* to *server_protocol*.
1943 If *expect_success* is true, assert that the connection succeeds,
1944 if it's false, assert that the connection fails.
1945 Also, if *expect_success* is a string, assert that it is the protocol
1946 version actually used by the connection.
1947 """
Benjamin Peterson5b63acd2008-03-29 15:24:25 +00001948 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +00001949 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +00001950 certtype = {
1951 ssl.CERT_NONE: "CERT_NONE",
1952 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1953 ssl.CERT_REQUIRED: "CERT_REQUIRED",
1954 }[certsreqs]
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001955 if support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +00001956 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +00001957 sys.stdout.write(formatstr %
1958 (ssl.get_protocol_name(client_protocol),
1959 ssl.get_protocol_name(server_protocol),
1960 certtype))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05001961 client_context = ssl.SSLContext(client_protocol)
1962 client_context.options |= client_options
1963 server_context = ssl.SSLContext(server_protocol)
1964 server_context.options |= server_options
1965
1966 # NOTE: we must enable "ALL" ciphers on the client, otherwise an
1967 # SSLv23 client will send an SSLv3 hello (rather than SSLv2)
1968 # starting from OpenSSL 1.0.0 (see issue #8322).
1969 if client_context.protocol == ssl.PROTOCOL_SSLv23:
1970 client_context.set_ciphers("ALL")
1971
1972 for ctx in (client_context, server_context):
1973 ctx.verify_mode = certsreqs
1974 ctx.load_cert_chain(CERTFILE)
1975 ctx.load_verify_locations(CERTFILE)
Bill Janssen98d19da2007-09-10 21:51:02 +00001976 try:
Alex Gaynore98205d2014-09-04 13:33:22 -07001977 stats = server_params_test(client_context, server_context,
1978 chatty=False, connectionchatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +00001979 # Protocol mismatch can result in either an SSLError, or a
1980 # "Connection reset by peer" error.
1981 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +00001982 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +00001983 raise
Antoine Pitroudb187842010-04-27 10:32:58 +00001984 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +00001985 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +00001986 raise
Bill Janssen98d19da2007-09-10 21:51:02 +00001987 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +00001988 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +00001989 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +00001990 "Client protocol %s succeeded with server protocol %s!"
1991 % (ssl.get_protocol_name(client_protocol),
1992 ssl.get_protocol_name(server_protocol)))
Alex Gaynore98205d2014-09-04 13:33:22 -07001993 elif (expect_success is not True
1994 and expect_success != stats['version']):
1995 raise AssertionError("version mismatch: expected %r, got %r"
1996 % (expect_success, stats['version']))
Bill Janssen98d19da2007-09-10 21:51:02 +00001997
1998
Bill Janssen934b16d2008-06-28 22:19:33 +00001999 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +00002000
Antoine Pitroud75efd92010-08-04 17:38:33 +00002001 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002002 def test_echo(self):
2003 """Basic test of an SSL client connecting to a server"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002004 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002005 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002006 for protocol in PROTOCOLS:
2007 context = ssl.SSLContext(protocol)
2008 context.load_cert_chain(CERTFILE)
2009 server_params_test(context, context,
2010 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00002011
Antoine Pitrou3945c862010-04-28 21:11:01 +00002012 def test_getpeercert(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002013 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002014 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002015 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2016 context.verify_mode = ssl.CERT_REQUIRED
2017 context.load_verify_locations(CERTFILE)
2018 context.load_cert_chain(CERTFILE)
2019 server = ThreadedEchoServer(context=context, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002020 with server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002021 s = context.wrap_socket(socket.socket(),
2022 do_handshake_on_connect=False)
Antoine Pitroudb187842010-04-27 10:32:58 +00002023 s.connect((HOST, server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002024 # getpeercert() raise ValueError while the handshake isn't
2025 # done.
2026 with self.assertRaises(ValueError):
2027 s.getpeercert()
2028 s.do_handshake()
Antoine Pitroudb187842010-04-27 10:32:58 +00002029 cert = s.getpeercert()
2030 self.assertTrue(cert, "Can't get peer certificate.")
2031 cipher = s.cipher()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002032 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002033 sys.stdout.write(pprint.pformat(cert) + '\n')
2034 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
2035 if 'subject' not in cert:
2036 self.fail("No subject field in certificate: %s." %
2037 pprint.pformat(cert))
2038 if ((('organizationName', 'Python Software Foundation'),)
2039 not in cert['subject']):
2040 self.fail(
2041 "Missing or invalid 'organizationName' field in certificate subject; "
2042 "should be 'Python Software Foundation'.")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002043 self.assertIn('notBefore', cert)
2044 self.assertIn('notAfter', cert)
2045 before = ssl.cert_time_to_seconds(cert['notBefore'])
2046 after = ssl.cert_time_to_seconds(cert['notAfter'])
2047 self.assertLess(before, after)
Antoine Pitroudb187842010-04-27 10:32:58 +00002048 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00002049
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002050 @unittest.skipUnless(have_verify_flags(),
2051 "verify_flags need OpenSSL > 0.9.8")
2052 def test_crl_check(self):
2053 if support.verbose:
2054 sys.stdout.write("\n")
2055
2056 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2057 server_context.load_cert_chain(SIGNED_CERTFILE)
2058
2059 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2060 context.verify_mode = ssl.CERT_REQUIRED
2061 context.load_verify_locations(SIGNING_CA)
2062 self.assertEqual(context.verify_flags, ssl.VERIFY_DEFAULT)
2063
2064 # VERIFY_DEFAULT should pass
2065 server = ThreadedEchoServer(context=server_context, chatty=True)
2066 with server:
2067 with closing(context.wrap_socket(socket.socket())) as s:
2068 s.connect((HOST, server.port))
2069 cert = s.getpeercert()
2070 self.assertTrue(cert, "Can't get peer certificate.")
2071
2072 # VERIFY_CRL_CHECK_LEAF without a loaded CRL file fails
2073 context.verify_flags |= ssl.VERIFY_CRL_CHECK_LEAF
2074
2075 server = ThreadedEchoServer(context=server_context, chatty=True)
2076 with server:
2077 with closing(context.wrap_socket(socket.socket())) as s:
2078 with self.assertRaisesRegexp(ssl.SSLError,
2079 "certificate verify failed"):
2080 s.connect((HOST, server.port))
2081
2082 # now load a CRL file. The CRL file is signed by the CA.
2083 context.load_verify_locations(CRLFILE)
2084
2085 server = ThreadedEchoServer(context=server_context, chatty=True)
2086 with server:
2087 with closing(context.wrap_socket(socket.socket())) as s:
2088 s.connect((HOST, server.port))
2089 cert = s.getpeercert()
2090 self.assertTrue(cert, "Can't get peer certificate.")
2091
2092 @needs_sni
2093 def test_check_hostname(self):
2094 if support.verbose:
2095 sys.stdout.write("\n")
2096
2097 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2098 server_context.load_cert_chain(SIGNED_CERTFILE)
2099
2100 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2101 context.verify_mode = ssl.CERT_REQUIRED
2102 context.check_hostname = True
2103 context.load_verify_locations(SIGNING_CA)
2104
2105 # correct hostname should verify
2106 server = ThreadedEchoServer(context=server_context, chatty=True)
2107 with server:
2108 with closing(context.wrap_socket(socket.socket(),
2109 server_hostname="localhost")) as s:
2110 s.connect((HOST, server.port))
2111 cert = s.getpeercert()
2112 self.assertTrue(cert, "Can't get peer certificate.")
2113
2114 # incorrect hostname should raise an exception
2115 server = ThreadedEchoServer(context=server_context, chatty=True)
2116 with server:
2117 with closing(context.wrap_socket(socket.socket(),
2118 server_hostname="invalid")) as s:
2119 with self.assertRaisesRegexp(ssl.CertificateError,
2120 "hostname 'invalid' doesn't match u?'localhost'"):
2121 s.connect((HOST, server.port))
2122
2123 # missing server_hostname arg should cause an exception, too
2124 server = ThreadedEchoServer(context=server_context, chatty=True)
2125 with server:
2126 with closing(socket.socket()) as s:
2127 with self.assertRaisesRegexp(ValueError,
2128 "check_hostname requires server_hostname"):
2129 context.wrap_socket(s)
2130
Antoine Pitrou3945c862010-04-28 21:11:01 +00002131 def test_empty_cert(self):
2132 """Connecting with an empty cert file"""
2133 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2134 "nullcert.pem"))
2135 def test_malformed_cert(self):
2136 """Connecting with a badly formatted certificate (syntax error)"""
2137 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2138 "badcert.pem"))
2139 def test_nonexisting_cert(self):
2140 """Connecting with a non-existing cert file"""
2141 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2142 "wrongcert.pem"))
2143 def test_malformed_key(self):
2144 """Connecting with a badly formatted key (syntax error)"""
2145 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
2146 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +00002147
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002148 def test_rude_shutdown(self):
2149 """A brutal shutdown of an SSL server should raise an OSError
2150 in the client when attempting handshake.
2151 """
2152 listener_ready = threading.Event()
2153 listener_gone = threading.Event()
2154
2155 s = socket.socket()
2156 port = support.bind_port(s, HOST)
2157
2158 # `listener` runs in a thread. It sits in an accept() until
2159 # the main thread connects. Then it rudely closes the socket,
2160 # and sets Event `listener_gone` to let the main thread know
2161 # the socket is gone.
2162 def listener():
2163 s.listen(5)
2164 listener_ready.set()
2165 newsock, addr = s.accept()
2166 newsock.close()
2167 s.close()
2168 listener_gone.set()
2169
2170 def connector():
2171 listener_ready.wait()
2172 with closing(socket.socket()) as c:
2173 c.connect((HOST, port))
2174 listener_gone.wait()
2175 try:
2176 ssl_sock = ssl.wrap_socket(c)
Benjamin Petersone208b572014-08-20 14:49:08 -05002177 except socket.error:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002178 pass
2179 else:
2180 self.fail('connecting to closed SSL socket should have failed')
2181
2182 t = threading.Thread(target=listener)
2183 t.start()
2184 try:
2185 connector()
2186 finally:
2187 t.join()
2188
Antoine Pitroud75efd92010-08-04 17:38:33 +00002189 @skip_if_broken_ubuntu_ssl
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002190 @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
2191 "OpenSSL is compiled without SSLv2 support")
Antoine Pitrou3945c862010-04-28 21:11:01 +00002192 def test_protocol_sslv2(self):
2193 """Connecting to an SSLv2 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002194 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002195 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00002196 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
2197 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
2198 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
Antoine Pitrou3b2afbb2014-01-09 19:52:12 +01002199 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002200 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
2201 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002202 # SSLv23 client with specific SSL options
2203 if no_sslv2_implies_sslv3_hello():
2204 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
2205 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2206 client_options=ssl.OP_NO_SSLv2)
2207 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2208 client_options=ssl.OP_NO_SSLv3)
2209 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
2210 client_options=ssl.OP_NO_TLSv1)
Bill Janssen98d19da2007-09-10 21:51:02 +00002211
Antoine Pitroud75efd92010-08-04 17:38:33 +00002212 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002213 def test_protocol_sslv23(self):
2214 """Connecting to an SSLv23 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002215 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002216 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002217 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2218 try:
2219 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
2220 except socket.error as x:
2221 # this fails on some older versions of OpenSSL (0.9.7l, for instance)
2222 if support.verbose:
2223 sys.stdout.write(
2224 " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
2225 % str(x))
Alex Gaynore98205d2014-09-04 13:33:22 -07002226 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3')
Antoine Pitrou3945c862010-04-28 21:11:01 +00002227 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
Alex Gaynore98205d2014-09-04 13:33:22 -07002228 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1')
Bill Janssen98d19da2007-09-10 21:51:02 +00002229
Alex Gaynore98205d2014-09-04 13:33:22 -07002230 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002231 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
Alex Gaynore98205d2014-09-04 13:33:22 -07002232 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00002233
Alex Gaynore98205d2014-09-04 13:33:22 -07002234 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002235 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
Alex Gaynore98205d2014-09-04 13:33:22 -07002236 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00002237
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002238 # Server with specific SSL options
2239 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
2240 server_options=ssl.OP_NO_SSLv3)
2241 # Will choose TLSv1
2242 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
2243 server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
2244 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
2245 server_options=ssl.OP_NO_TLSv1)
2246
2247
Antoine Pitroud75efd92010-08-04 17:38:33 +00002248 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002249 def test_protocol_sslv3(self):
2250 """Connecting to an SSLv3 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002251 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002252 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002253 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3')
2254 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_OPTIONAL)
2255 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, 'SSLv3', ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02002256 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2257 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002258 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
2259 client_options=ssl.OP_NO_SSLv3)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002260 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002261 if no_sslv2_implies_sslv3_hello():
2262 # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
Alex Gaynore98205d2014-09-04 13:33:22 -07002263 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, 'SSLv3',
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002264 client_options=ssl.OP_NO_SSLv2)
Bill Janssen98d19da2007-09-10 21:51:02 +00002265
Antoine Pitroud75efd92010-08-04 17:38:33 +00002266 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00002267 def test_protocol_tlsv1(self):
2268 """Connecting to a TLSv1 server with various client options"""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002269 if support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +00002270 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002271 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1')
2272 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_OPTIONAL)
2273 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, 'TLSv1', ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02002274 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2275 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002276 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002277 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
2278 client_options=ssl.OP_NO_TLSv1)
2279
2280 @skip_if_broken_ubuntu_ssl
2281 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_1"),
2282 "TLS version 1.1 not supported.")
2283 def test_protocol_tlsv1_1(self):
2284 """Connecting to a TLSv1.1 server with various client options.
2285 Testing against older TLS versions."""
2286 if support.verbose:
2287 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002288 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002289 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2290 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv2, False)
2291 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv3, False)
2292 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_SSLv23, False,
2293 client_options=ssl.OP_NO_TLSv1_1)
2294
Alex Gaynore98205d2014-09-04 13:33:22 -07002295 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_1, 'TLSv1.1')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002296 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1, False)
2297 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_1, False)
2298
2299
2300 @skip_if_broken_ubuntu_ssl
2301 @unittest.skipUnless(hasattr(ssl, "PROTOCOL_TLSv1_2"),
2302 "TLS version 1.2 not supported.")
2303 def test_protocol_tlsv1_2(self):
2304 """Connecting to a TLSv1.2 server with various client options.
2305 Testing against older TLS versions."""
2306 if support.verbose:
2307 sys.stdout.write("\n")
Alex Gaynore98205d2014-09-04 13:33:22 -07002308 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2',
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002309 server_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,
2310 client_options=ssl.OP_NO_SSLv3|ssl.OP_NO_SSLv2,)
2311 if hasattr(ssl, 'PROTOCOL_SSLv2'):
2312 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv2, False)
2313 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv3, False)
2314 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_SSLv23, False,
2315 client_options=ssl.OP_NO_TLSv1_2)
2316
Alex Gaynore98205d2014-09-04 13:33:22 -07002317 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1_2, 'TLSv1.2')
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002318 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1, False)
2319 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1_2, False)
2320 try_protocol_combo(ssl.PROTOCOL_TLSv1_2, ssl.PROTOCOL_TLSv1_1, False)
2321 try_protocol_combo(ssl.PROTOCOL_TLSv1_1, ssl.PROTOCOL_TLSv1_2, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00002322
Antoine Pitrou3945c862010-04-28 21:11:01 +00002323 def test_starttls(self):
2324 """Switching from clear text to encrypted and back again."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002325 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 +00002326
Trent Nelsone41b0062008-04-08 23:47:30 +00002327 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00002328 ssl_version=ssl.PROTOCOL_TLSv1,
2329 starttls_server=True,
2330 chatty=True,
2331 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00002332 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002333 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00002334 s = socket.socket()
2335 s.setblocking(1)
2336 s.connect((HOST, server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002337 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002338 sys.stdout.write("\n")
2339 for indata in msgs:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002340 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002341 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002342 " client: sending %r...\n" % indata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002343 if wrapped:
2344 conn.write(indata)
2345 outdata = conn.read()
2346 else:
2347 s.send(indata)
2348 outdata = s.recv(1024)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002349 msg = outdata.strip().lower()
2350 if indata == b"STARTTLS" and msg.startswith(b"ok"):
Antoine Pitrou3945c862010-04-28 21:11:01 +00002351 # STARTTLS ok, switch to secure mode
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002352 if support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00002353 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002354 " client: read %r from server, starting TLS...\n"
2355 % msg)
Antoine Pitroudb187842010-04-27 10:32:58 +00002356 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
2357 wrapped = True
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002358 elif indata == b"ENDTLS" and msg.startswith(b"ok"):
Antoine Pitrou3945c862010-04-28 21:11:01 +00002359 # ENDTLS ok, switch back to clear text
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002360 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002361 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002362 " client: read %r from server, ending TLS...\n"
2363 % msg)
Antoine Pitroudb187842010-04-27 10:32:58 +00002364 s = conn.unwrap()
2365 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00002366 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002367 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002368 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002369 " client: read %r from server\n" % msg)
2370 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002371 sys.stdout.write(" client: closing connection.\n")
2372 if wrapped:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002373 conn.write(b"over\n")
Antoine Pitroudb187842010-04-27 10:32:58 +00002374 else:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002375 s.send(b"over\n")
2376 if wrapped:
2377 conn.close()
2378 else:
2379 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00002380
Antoine Pitrou3945c862010-04-28 21:11:01 +00002381 def test_socketserver(self):
2382 """Using a SocketServer to create and manage SSL connections."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002383 server = make_https_server(self, certfile=CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00002384 # try to connect
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002385 if support.verbose:
2386 sys.stdout.write('\n')
2387 with open(CERTFILE, 'rb') as f:
2388 d1 = f.read()
2389 d2 = ''
2390 # now fetch the same data from the HTTPS server
2391 url = 'https://%s:%d/%s' % (
2392 HOST, server.port, os.path.split(CERTFILE)[1])
Victor Stinnera3acea32014-09-05 21:05:05 +02002393 with support.check_py3k_warnings():
2394 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00002395 try:
Bill Janssen296a59d2007-09-16 22:06:00 +00002396 dlen = f.info().getheader("content-length")
2397 if dlen and (int(dlen) > 0):
2398 d2 = f.read(int(dlen))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002399 if support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00002400 sys.stdout.write(
2401 " client: read %d bytes from remote server '%s'\n"
2402 % (len(d2), server))
Bill Janssen296a59d2007-09-16 22:06:00 +00002403 finally:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002404 f.close()
2405 self.assertEqual(d1, d2)
Bill Janssen934b16d2008-06-28 22:19:33 +00002406
Antoine Pitrou3945c862010-04-28 21:11:01 +00002407 def test_asyncore_server(self):
2408 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00002409 indata = "TEST MESSAGE of mixed case\n"
2410
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002411 if support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +00002412 sys.stdout.write("\n")
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002413
2414 indata = b"FOO\n"
Bill Janssen934b16d2008-06-28 22:19:33 +00002415 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002416 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00002417 s = ssl.wrap_socket(socket.socket())
2418 s.connect(('127.0.0.1', server.port))
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002419 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002420 sys.stdout.write(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002421 " client: sending %r...\n" % indata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002422 s.write(indata)
2423 outdata = s.read()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002424 if support.verbose:
2425 sys.stdout.write(" client: read %r\n" % outdata)
Antoine Pitroudb187842010-04-27 10:32:58 +00002426 if outdata != indata.lower():
2427 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002428 "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
2429 % (outdata[:20], len(outdata),
2430 indata[:20].lower(), len(indata)))
2431 s.write(b"over\n")
2432 if support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00002433 sys.stdout.write(" client: closing connection.\n")
2434 s.close()
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002435 if support.verbose:
2436 sys.stdout.write(" client: connection closed.\n")
Bill Janssen934b16d2008-06-28 22:19:33 +00002437
Antoine Pitrou3945c862010-04-28 21:11:01 +00002438 def test_recv_send(self):
2439 """Test recv(), send() and friends."""
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002440 if support.verbose:
Bill Janssen61c001a2008-09-08 16:37:24 +00002441 sys.stdout.write("\n")
2442
2443 server = ThreadedEchoServer(CERTFILE,
2444 certreqs=ssl.CERT_NONE,
2445 ssl_version=ssl.PROTOCOL_TLSv1,
2446 cacerts=CERTFILE,
2447 chatty=True,
2448 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01002449 with server:
2450 s = ssl.wrap_socket(socket.socket(),
2451 server_side=False,
2452 certfile=CERTFILE,
2453 ca_certs=CERTFILE,
2454 cert_reqs=ssl.CERT_NONE,
2455 ssl_version=ssl.PROTOCOL_TLSv1)
2456 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00002457 # helper methods for standardising recv* method signatures
2458 def _recv_into():
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002459 b = bytearray(b"\0"*100)
Bill Janssen61c001a2008-09-08 16:37:24 +00002460 count = s.recv_into(b)
2461 return b[:count]
2462
2463 def _recvfrom_into():
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002464 b = bytearray(b"\0"*100)
Bill Janssen61c001a2008-09-08 16:37:24 +00002465 count, addr = s.recvfrom_into(b)
2466 return b[:count]
2467
2468 # (name, method, whether to expect success, *args)
2469 send_methods = [
2470 ('send', s.send, True, []),
2471 ('sendto', s.sendto, False, ["some.address"]),
2472 ('sendall', s.sendall, True, []),
2473 ]
2474 recv_methods = [
2475 ('recv', s.recv, True, []),
2476 ('recvfrom', s.recvfrom, False, ["some.address"]),
2477 ('recv_into', _recv_into, True, []),
2478 ('recvfrom_into', _recvfrom_into, False, []),
2479 ]
2480 data_prefix = u"PREFIX_"
2481
2482 for meth_name, send_meth, expect_success, args in send_methods:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002483 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen61c001a2008-09-08 16:37:24 +00002484 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002485 send_meth(indata, *args)
Bill Janssen61c001a2008-09-08 16:37:24 +00002486 outdata = s.read()
Bill Janssen61c001a2008-09-08 16:37:24 +00002487 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002488 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002489 "While sending with <<{name:s}>> bad data "
2490 "<<{outdata:r}>> ({nout:d}) received; "
2491 "expected <<{indata:r}>> ({nin:d})\n".format(
2492 name=meth_name, outdata=outdata[:20],
2493 nout=len(outdata),
2494 indata=indata[:20], nin=len(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002495 )
2496 )
2497 except ValueError as e:
2498 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002499 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002500 "Failed to send with method <<{name:s}>>; "
2501 "expected to succeed.\n".format(name=meth_name)
Bill Janssen61c001a2008-09-08 16:37:24 +00002502 )
2503 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002504 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002505 "Method <<{name:s}>> failed with unexpected "
2506 "exception message: {exp:s}\n".format(
2507 name=meth_name, exp=e
Bill Janssen61c001a2008-09-08 16:37:24 +00002508 )
2509 )
2510
2511 for meth_name, recv_meth, expect_success, args in recv_methods:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002512 indata = (data_prefix + meth_name).encode('ascii')
Bill Janssen61c001a2008-09-08 16:37:24 +00002513 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002514 s.send(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002515 outdata = recv_meth(*args)
Bill Janssen61c001a2008-09-08 16:37:24 +00002516 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002517 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002518 "While receiving with <<{name:s}>> bad data "
2519 "<<{outdata:r}>> ({nout:d}) received; "
2520 "expected <<{indata:r}>> ({nin:d})\n".format(
2521 name=meth_name, outdata=outdata[:20],
2522 nout=len(outdata),
2523 indata=indata[:20], nin=len(indata)
Bill Janssen61c001a2008-09-08 16:37:24 +00002524 )
2525 )
2526 except ValueError as e:
2527 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002528 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002529 "Failed to receive with method <<{name:s}>>; "
2530 "expected to succeed.\n".format(name=meth_name)
Bill Janssen61c001a2008-09-08 16:37:24 +00002531 )
2532 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00002533 self.fail(
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002534 "Method <<{name:s}>> failed with unexpected "
2535 "exception message: {exp:s}\n".format(
2536 name=meth_name, exp=e
Bill Janssen61c001a2008-09-08 16:37:24 +00002537 )
2538 )
2539 # consume data
2540 s.read()
2541
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002542 s.write(b"over\n")
Bill Janssen61c001a2008-09-08 16:37:24 +00002543 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00002544
Antoine Pitroufc69af12010-04-24 20:04:58 +00002545 def test_handshake_timeout(self):
2546 # Issue #5103: SSL handshake must respect the socket timeout
2547 server = socket.socket(socket.AF_INET)
2548 host = "127.0.0.1"
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002549 port = support.bind_port(server)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002550 started = threading.Event()
2551 finish = False
2552
2553 def serve():
2554 server.listen(5)
2555 started.set()
2556 conns = []
2557 while not finish:
2558 r, w, e = select.select([server], [], [], 0.1)
2559 if server in r:
2560 # Let the socket hang around rather than having
2561 # it closed by garbage collection.
2562 conns.append(server.accept()[0])
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002563 for sock in conns:
2564 sock.close()
Antoine Pitroufc69af12010-04-24 20:04:58 +00002565
2566 t = threading.Thread(target=serve)
2567 t.start()
2568 started.wait()
2569
2570 try:
2571 try:
2572 c = socket.socket(socket.AF_INET)
2573 c.settimeout(0.2)
2574 c.connect((host, port))
2575 # Will attempt handshake and time out
2576 self.assertRaisesRegexp(ssl.SSLError, "timed out",
2577 ssl.wrap_socket, c)
2578 finally:
2579 c.close()
2580 try:
2581 c = socket.socket(socket.AF_INET)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002582 c = ssl.wrap_socket(c)
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002583 c.settimeout(0.2)
Antoine Pitroufc69af12010-04-24 20:04:58 +00002584 # Will attempt handshake and time out
2585 self.assertRaisesRegexp(ssl.SSLError, "timed out",
2586 c.connect, (host, port))
2587 finally:
2588 c.close()
2589 finally:
2590 finish = True
2591 t.join()
2592 server.close()
2593
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002594 def test_server_accept(self):
2595 # Issue #16357: accept() on a SSLSocket created through
2596 # SSLContext.wrap_socket().
2597 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2598 context.verify_mode = ssl.CERT_REQUIRED
2599 context.load_verify_locations(CERTFILE)
2600 context.load_cert_chain(CERTFILE)
2601 server = socket.socket(socket.AF_INET)
2602 host = "127.0.0.1"
2603 port = support.bind_port(server)
2604 server = context.wrap_socket(server, server_side=True)
2605
2606 evt = threading.Event()
2607 remote = [None]
2608 peer = [None]
2609 def serve():
2610 server.listen(5)
2611 # Block on the accept and wait on the connection to close.
2612 evt.set()
2613 remote[0], peer[0] = server.accept()
2614 remote[0].recv(1)
2615
2616 t = threading.Thread(target=serve)
2617 t.start()
2618 # Client wait until server setup and perform a connect.
2619 evt.wait()
2620 client = context.wrap_socket(socket.socket())
2621 client.connect((host, port))
2622 client_addr = client.getsockname()
2623 client.close()
2624 t.join()
2625 remote[0].close()
2626 server.close()
2627 # Sanity checks.
2628 self.assertIsInstance(remote[0], ssl.SSLSocket)
2629 self.assertEqual(peer[0], client_addr)
2630
2631 def test_getpeercert_enotconn(self):
2632 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2633 with closing(context.wrap_socket(socket.socket())) as sock:
2634 with self.assertRaises(socket.error) as cm:
2635 sock.getpeercert()
2636 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2637
2638 def test_do_handshake_enotconn(self):
2639 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2640 with closing(context.wrap_socket(socket.socket())) as sock:
2641 with self.assertRaises(socket.error) as cm:
2642 sock.do_handshake()
2643 self.assertEqual(cm.exception.errno, errno.ENOTCONN)
2644
Antoine Pitroud76088d2012-01-03 22:46:48 +01002645 def test_default_ciphers(self):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002646 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2647 try:
2648 # Force a set of weak ciphers on our client context
2649 context.set_ciphers("DES")
2650 except ssl.SSLError:
2651 self.skipTest("no DES cipher available")
Antoine Pitroud76088d2012-01-03 22:46:48 +01002652 with ThreadedEchoServer(CERTFILE,
2653 ssl_version=ssl.PROTOCOL_SSLv23,
2654 chatty=False) as server:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002655 with closing(context.wrap_socket(socket.socket())) as s:
2656 with self.assertRaises(ssl.SSLError):
Antoine Pitroud76088d2012-01-03 22:46:48 +01002657 s.connect((HOST, server.port))
Antoine Pitroud76088d2012-01-03 22:46:48 +01002658 self.assertIn("no shared cipher", str(server.conn_errors[0]))
2659
Alex Gaynore98205d2014-09-04 13:33:22 -07002660 def test_version_basic(self):
2661 """
2662 Basic tests for SSLSocket.version().
2663 More tests are done in the test_protocol_*() methods.
2664 """
2665 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2666 with ThreadedEchoServer(CERTFILE,
2667 ssl_version=ssl.PROTOCOL_TLSv1,
2668 chatty=False) as server:
2669 with closing(context.wrap_socket(socket.socket())) as s:
2670 self.assertIs(s.version(), None)
2671 s.connect((HOST, server.port))
2672 self.assertEqual(s.version(), "TLSv1")
2673 self.assertIs(s.version(), None)
2674
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002675 @unittest.skipUnless(ssl.HAS_ECDH, "test requires ECDH-enabled OpenSSL")
2676 def test_default_ecdh_curve(self):
2677 # Issue #21015: elliptic curve-based Diffie Hellman key exchange
2678 # should be enabled by default on SSL contexts.
2679 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2680 context.load_cert_chain(CERTFILE)
2681 # Prior to OpenSSL 1.0.0, ECDH ciphers have to be enabled
2682 # explicitly using the 'ECCdraft' cipher alias. Otherwise,
2683 # our default cipher list should prefer ECDH-based ciphers
2684 # automatically.
2685 if ssl.OPENSSL_VERSION_INFO < (1, 0, 0):
2686 context.set_ciphers("ECCdraft:ECDH")
2687 with ThreadedEchoServer(context=context) as server:
2688 with closing(context.wrap_socket(socket.socket())) as s:
2689 s.connect((HOST, server.port))
2690 self.assertIn("ECDH", s.cipher()[0])
2691
2692 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
2693 "'tls-unique' channel binding not available")
2694 def test_tls_unique_channel_binding(self):
2695 """Test tls-unique channel binding."""
2696 if support.verbose:
2697 sys.stdout.write("\n")
2698
2699 server = ThreadedEchoServer(CERTFILE,
2700 certreqs=ssl.CERT_NONE,
2701 ssl_version=ssl.PROTOCOL_TLSv1,
2702 cacerts=CERTFILE,
2703 chatty=True,
2704 connectionchatty=False)
2705 with server:
2706 s = ssl.wrap_socket(socket.socket(),
2707 server_side=False,
2708 certfile=CERTFILE,
2709 ca_certs=CERTFILE,
2710 cert_reqs=ssl.CERT_NONE,
2711 ssl_version=ssl.PROTOCOL_TLSv1)
2712 s.connect((HOST, server.port))
2713 # get the data
2714 cb_data = s.get_channel_binding("tls-unique")
2715 if support.verbose:
2716 sys.stdout.write(" got channel binding data: {0!r}\n"
2717 .format(cb_data))
2718
2719 # check if it is sane
2720 self.assertIsNotNone(cb_data)
2721 self.assertEqual(len(cb_data), 12) # True for TLSv1
2722
2723 # and compare with the peers version
2724 s.write(b"CB tls-unique\n")
2725 peer_data_repr = s.read().strip()
2726 self.assertEqual(peer_data_repr,
2727 repr(cb_data).encode("us-ascii"))
2728 s.close()
2729
2730 # now, again
2731 s = ssl.wrap_socket(socket.socket(),
2732 server_side=False,
2733 certfile=CERTFILE,
2734 ca_certs=CERTFILE,
2735 cert_reqs=ssl.CERT_NONE,
2736 ssl_version=ssl.PROTOCOL_TLSv1)
2737 s.connect((HOST, server.port))
2738 new_cb_data = s.get_channel_binding("tls-unique")
2739 if support.verbose:
2740 sys.stdout.write(" got another channel binding data: {0!r}\n"
2741 .format(new_cb_data))
2742 # is it really unique
2743 self.assertNotEqual(cb_data, new_cb_data)
2744 self.assertIsNotNone(cb_data)
2745 self.assertEqual(len(cb_data), 12) # True for TLSv1
2746 s.write(b"CB tls-unique\n")
2747 peer_data_repr = s.read().strip()
2748 self.assertEqual(peer_data_repr,
2749 repr(new_cb_data).encode("us-ascii"))
2750 s.close()
2751
2752 def test_compression(self):
2753 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2754 context.load_cert_chain(CERTFILE)
2755 stats = server_params_test(context, context,
2756 chatty=True, connectionchatty=True)
2757 if support.verbose:
2758 sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
2759 self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
2760
2761 @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
2762 "ssl.OP_NO_COMPRESSION needed for this test")
2763 def test_compression_disabled(self):
2764 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2765 context.load_cert_chain(CERTFILE)
2766 context.options |= ssl.OP_NO_COMPRESSION
2767 stats = server_params_test(context, context,
2768 chatty=True, connectionchatty=True)
2769 self.assertIs(stats['compression'], None)
2770
2771 def test_dh_params(self):
2772 # Check we can get a connection with ephemeral Diffie-Hellman
2773 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2774 context.load_cert_chain(CERTFILE)
2775 context.load_dh_params(DHFILE)
2776 context.set_ciphers("kEDH")
2777 stats = server_params_test(context, context,
2778 chatty=True, connectionchatty=True)
2779 cipher = stats["cipher"][0]
2780 parts = cipher.split("-")
2781 if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
2782 self.fail("Non-DH cipher: " + cipher[0])
2783
2784 def test_selected_npn_protocol(self):
2785 # selected_npn_protocol() is None unless NPN is used
2786 context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2787 context.load_cert_chain(CERTFILE)
2788 stats = server_params_test(context, context,
2789 chatty=True, connectionchatty=True)
2790 self.assertIs(stats['client_npn_protocol'], None)
2791
2792 @unittest.skipUnless(ssl.HAS_NPN, "NPN support needed for this test")
2793 def test_npn_protocols(self):
2794 server_protocols = ['http/1.1', 'spdy/2']
2795 protocol_tests = [
2796 (['http/1.1', 'spdy/2'], 'http/1.1'),
2797 (['spdy/2', 'http/1.1'], 'http/1.1'),
2798 (['spdy/2', 'test'], 'spdy/2'),
2799 (['abc', 'def'], 'abc')
2800 ]
2801 for client_protocols, expected in protocol_tests:
2802 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2803 server_context.load_cert_chain(CERTFILE)
2804 server_context.set_npn_protocols(server_protocols)
2805 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2806 client_context.load_cert_chain(CERTFILE)
2807 client_context.set_npn_protocols(client_protocols)
2808 stats = server_params_test(client_context, server_context,
2809 chatty=True, connectionchatty=True)
2810
2811 msg = "failed trying %s (s) and %s (c).\n" \
2812 "was expecting %s, but got %%s from the %%s" \
2813 % (str(server_protocols), str(client_protocols),
2814 str(expected))
2815 client_result = stats['client_npn_protocol']
2816 self.assertEqual(client_result, expected, msg % (client_result, "client"))
2817 server_result = stats['server_npn_protocols'][-1] \
2818 if len(stats['server_npn_protocols']) else 'nothing'
2819 self.assertEqual(server_result, expected, msg % (server_result, "server"))
2820
2821 def sni_contexts(self):
2822 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2823 server_context.load_cert_chain(SIGNED_CERTFILE)
2824 other_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2825 other_context.load_cert_chain(SIGNED_CERTFILE2)
2826 client_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
2827 client_context.verify_mode = ssl.CERT_REQUIRED
2828 client_context.load_verify_locations(SIGNING_CA)
2829 return server_context, other_context, client_context
2830
2831 def check_common_name(self, stats, name):
2832 cert = stats['peercert']
2833 self.assertIn((('commonName', name),), cert['subject'])
2834
2835 @needs_sni
2836 def test_sni_callback(self):
2837 calls = []
2838 server_context, other_context, client_context = self.sni_contexts()
2839
2840 def servername_cb(ssl_sock, server_name, initial_context):
2841 calls.append((server_name, initial_context))
2842 if server_name is not None:
2843 ssl_sock.context = other_context
2844 server_context.set_servername_callback(servername_cb)
2845
2846 stats = server_params_test(client_context, server_context,
2847 chatty=True,
2848 sni_name='supermessage')
2849 # The hostname was fetched properly, and the certificate was
2850 # changed for the connection.
2851 self.assertEqual(calls, [("supermessage", server_context)])
2852 # CERTFILE4 was selected
2853 self.check_common_name(stats, 'fakehostname')
2854
2855 calls = []
2856 # The callback is called with server_name=None
2857 stats = server_params_test(client_context, server_context,
2858 chatty=True,
2859 sni_name=None)
2860 self.assertEqual(calls, [(None, server_context)])
2861 self.check_common_name(stats, 'localhost')
2862
2863 # Check disabling the callback
2864 calls = []
2865 server_context.set_servername_callback(None)
2866
2867 stats = server_params_test(client_context, server_context,
2868 chatty=True,
2869 sni_name='notfunny')
2870 # Certificate didn't change
2871 self.check_common_name(stats, 'localhost')
2872 self.assertEqual(calls, [])
2873
2874 @needs_sni
2875 def test_sni_callback_alert(self):
2876 # Returning a TLS alert is reflected to the connecting client
2877 server_context, other_context, client_context = self.sni_contexts()
2878
2879 def cb_returning_alert(ssl_sock, server_name, initial_context):
2880 return ssl.ALERT_DESCRIPTION_ACCESS_DENIED
2881 server_context.set_servername_callback(cb_returning_alert)
2882
2883 with self.assertRaises(ssl.SSLError) as cm:
2884 stats = server_params_test(client_context, server_context,
2885 chatty=False,
2886 sni_name='supermessage')
2887 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_ACCESS_DENIED')
2888
2889 @needs_sni
2890 def test_sni_callback_raising(self):
2891 # Raising fails the connection with a TLS handshake failure alert.
2892 server_context, other_context, client_context = self.sni_contexts()
2893
2894 def cb_raising(ssl_sock, server_name, initial_context):
2895 1/0
2896 server_context.set_servername_callback(cb_raising)
2897
2898 with self.assertRaises(ssl.SSLError) as cm, \
2899 support.captured_stderr() as stderr:
2900 stats = server_params_test(client_context, server_context,
2901 chatty=False,
2902 sni_name='supermessage')
2903 self.assertEqual(cm.exception.reason, 'SSLV3_ALERT_HANDSHAKE_FAILURE')
2904 self.assertIn("ZeroDivisionError", stderr.getvalue())
2905
2906 @needs_sni
2907 def test_sni_callback_wrong_return_type(self):
2908 # Returning the wrong return type terminates the TLS connection
2909 # with an internal error alert.
2910 server_context, other_context, client_context = self.sni_contexts()
2911
2912 def cb_wrong_return_type(ssl_sock, server_name, initial_context):
2913 return "foo"
2914 server_context.set_servername_callback(cb_wrong_return_type)
2915
2916 with self.assertRaises(ssl.SSLError) as cm, \
2917 support.captured_stderr() as stderr:
2918 stats = server_params_test(client_context, server_context,
2919 chatty=False,
2920 sni_name='supermessage')
2921 self.assertEqual(cm.exception.reason, 'TLSV1_ALERT_INTERNAL_ERROR')
2922 self.assertIn("TypeError", stderr.getvalue())
2923
2924 def test_read_write_after_close_raises_valuerror(self):
2925 context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
2926 context.verify_mode = ssl.CERT_REQUIRED
2927 context.load_verify_locations(CERTFILE)
2928 context.load_cert_chain(CERTFILE)
2929 server = ThreadedEchoServer(context=context, chatty=False)
2930
2931 with server:
2932 s = context.wrap_socket(socket.socket())
2933 s.connect((HOST, server.port))
2934 s.close()
2935
2936 self.assertRaises(ValueError, s.read, 1024)
2937 self.assertRaises(ValueError, s.write, b'hello')
2938
Bill Janssen61c001a2008-09-08 16:37:24 +00002939
Neal Norwitz9eb9b102007-08-27 01:15:33 +00002940def test_main(verbose=False):
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002941 if support.verbose:
2942 plats = {
2943 'Linux': platform.linux_distribution,
2944 'Mac': platform.mac_ver,
2945 'Windows': platform.win32_ver,
2946 }
2947 for name, func in plats.items():
2948 plat = func()
2949 if plat and plat[0]:
2950 plat = '%s %r' % (name, plat)
2951 break
2952 else:
2953 plat = repr(platform.platform())
2954 print("test_ssl: testing with %r %r" %
2955 (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
2956 print(" under %s" % plat)
2957 print(" HAS_SNI = %r" % ssl.HAS_SNI)
2958 print(" OP_ALL = 0x%8x" % ssl.OP_ALL)
2959 try:
2960 print(" OP_NO_TLSv1_1 = 0x%8x" % ssl.OP_NO_TLSv1_1)
2961 except AttributeError:
2962 pass
Bill Janssen296a59d2007-09-16 22:06:00 +00002963
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002964 for filename in [
2965 CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
2966 ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
2967 SIGNED_CERTFILE, SIGNED_CERTFILE2, SIGNING_CA,
2968 BADCERT, BADKEY, EMPTYCERT]:
2969 if not os.path.exists(filename):
2970 raise support.TestFailed("Can't read certificate file %r" % filename)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00002971
Benjamin Peterson2f334562014-10-01 23:53:01 -04002972 tests = [ContextTests, BasicTests, BasicSocketTests, SSLErrorTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00002973
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002974 if support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00002975 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00002976
Bill Janssen98d19da2007-09-10 21:51:02 +00002977 if _have_threads:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002978 thread_info = support.threading_setup()
2979 if thread_info:
Bill Janssen934b16d2008-06-28 22:19:33 +00002980 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00002981
Antoine Pitrou3945c862010-04-28 21:11:01 +00002982 try:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002983 support.run_unittest(*tests)
Antoine Pitrou3945c862010-04-28 21:11:01 +00002984 finally:
2985 if _have_threads:
Benjamin Petersondaeb9252014-08-20 14:14:50 -05002986 support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00002987
2988if __name__ == "__main__":
2989 test_main()