blob: 6723865bf93e62e33be4b86213f6a3c0e0faed2e [file] [log] [blame]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001# Test the support for SSL and sockets
2
3import sys
4import unittest
5from test import test_support
Bill Janssen934b16d2008-06-28 22:19:33 +00006import asyncore
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00007import socket
Bill Janssen934b16d2008-06-28 22:19:33 +00008import select
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00009import time
Antoine Pitroub558f172010-04-23 23:25:45 +000010import gc
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000011import os
Antoine Pitroub558f172010-04-23 23:25:45 +000012import errno
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000013import pprint
Bill Janssen296a59d2007-09-16 22:06:00 +000014import urllib, urlparse
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000015import traceback
Antoine Pitroudfb299b2010-04-23 22:54:59 +000016import weakref
Antoine Pitroud75efd92010-08-04 17:38:33 +000017import functools
18import platform
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000019
Bill Janssen296a59d2007-09-16 22:06:00 +000020from BaseHTTPServer import HTTPServer
21from SimpleHTTPServer import SimpleHTTPRequestHandler
22
Victor Stinner2e7f39e2011-05-22 13:22:28 +020023ssl = test_support.import_module("ssl")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000024
Trent Nelsone41b0062008-04-08 23:47:30 +000025HOST = test_support.HOST
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000026CERTFILE = None
Bill Janssen296a59d2007-09-16 22:06:00 +000027SVN_PYTHON_ORG_ROOT_CERT = None
Christian Heimes88b174c2013-08-17 00:54:47 +020028NULLBYTECERT = None
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000029
Neal Norwitz3e533c22007-08-27 01:03:18 +000030def handle_error(prefix):
31 exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
Bill Janssen98d19da2007-09-10 21:51:02 +000032 if test_support.verbose:
33 sys.stdout.write(prefix + exc_format)
Neal Norwitz3e533c22007-08-27 01:03:18 +000034
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000035
36class BasicTests(unittest.TestCase):
37
Antoine Pitrou3945c862010-04-28 21:11:01 +000038 def test_sslwrap_simple(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +000039 # A crude test for the legacy API
Bill Jansseneb257ac2008-09-29 18:56:38 +000040 try:
41 ssl.sslwrap_simple(socket.socket(socket.AF_INET))
42 except IOError, e:
43 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
44 pass
45 else:
46 raise
47 try:
48 ssl.sslwrap_simple(socket.socket(socket.AF_INET)._sock)
49 except IOError, e:
50 if e.errno == 32: # broken pipe when ssl_sock.do_handshake(), this test doesn't care about that
51 pass
52 else:
53 raise
Neal Norwitz3e533c22007-08-27 01:03:18 +000054
Antoine Pitroud75efd92010-08-04 17:38:33 +000055# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
56def skip_if_broken_ubuntu_ssl(func):
Victor Stinnerb1241f92011-05-10 01:52:03 +020057 if hasattr(ssl, 'PROTOCOL_SSLv2'):
58 # We need to access the lower-level wrapper in order to create an
59 # implicit SSL context without trying to connect or listen.
Antoine Pitroud75efd92010-08-04 17:38:33 +000060 try:
Victor Stinnerb1241f92011-05-10 01:52:03 +020061 import _ssl
62 except ImportError:
63 # The returned function won't get executed, just ignore the error
64 pass
65 @functools.wraps(func)
66 def f(*args, **kwargs):
67 try:
68 s = socket.socket(socket.AF_INET)
69 _ssl.sslwrap(s._sock, 0, None, None,
70 ssl.CERT_NONE, ssl.PROTOCOL_SSLv2, None, None)
71 except ssl.SSLError as e:
72 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
73 platform.linux_distribution() == ('debian', 'squeeze/sid', '')
74 and 'Invalid SSL protocol variant specified' in str(e)):
75 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
76 return func(*args, **kwargs)
77 return f
78 else:
79 return func
Antoine Pitroud75efd92010-08-04 17:38:33 +000080
81
82class BasicSocketTests(unittest.TestCase):
83
Antoine Pitrou3945c862010-04-28 21:11:01 +000084 def test_constants(self):
Victor Stinnerb1241f92011-05-10 01:52:03 +020085 #ssl.PROTOCOL_SSLv2
Bill Janssen98d19da2007-09-10 21:51:02 +000086 ssl.PROTOCOL_SSLv23
87 ssl.PROTOCOL_SSLv3
88 ssl.PROTOCOL_TLSv1
89 ssl.CERT_NONE
90 ssl.CERT_OPTIONAL
91 ssl.CERT_REQUIRED
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +000092
Antoine Pitrou3945c862010-04-28 21:11:01 +000093 def test_random(self):
Bill Janssen98d19da2007-09-10 21:51:02 +000094 v = ssl.RAND_status()
95 if test_support.verbose:
96 sys.stdout.write("\n RAND_status is %d (%s)\n"
97 % (v, (v and "sufficient randomness") or
98 "insufficient randomness"))
Jesus Ceaa8a5b392012-09-11 01:55:04 +020099 self.assertRaises(TypeError, ssl.RAND_egd, 1)
100 self.assertRaises(TypeError, ssl.RAND_egd, 'foo', 1)
Bill Janssen98d19da2007-09-10 21:51:02 +0000101 ssl.RAND_add("this is a random string", 75.0)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000102
Antoine Pitrou3945c862010-04-28 21:11:01 +0000103 def test_parse_cert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000104 # note that this uses an 'unofficial' function in _ssl.c,
105 # provided solely for this test, to exercise the certificate
106 # parsing code
107 p = ssl._ssl._test_decode_cert(CERTFILE, False)
108 if test_support.verbose:
109 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200110 self.assertEqual(p['subject'],
Antoine Pitrou60982912013-02-16 21:39:28 +0100111 ((('countryName', 'XY'),),
112 (('localityName', 'Castle Anthrax'),),
113 (('organizationName', 'Python Software Foundation'),),
114 (('commonName', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200115 )
Antoine Pitrou60982912013-02-16 21:39:28 +0100116 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
Antoine Pitrouf06eb462011-10-01 19:30:58 +0200117 # Issue #13034: the subjectAltName in some certificates
118 # (notably projects.developer.nokia.com:443) wasn't parsed
119 p = ssl._ssl._test_decode_cert(NOKIACERT)
120 if test_support.verbose:
121 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
122 self.assertEqual(p['subjectAltName'],
123 (('DNS', 'projects.developer.nokia.com'),
124 ('DNS', 'projects.forum.nokia.com'))
125 )
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000126
Christian Heimes88b174c2013-08-17 00:54:47 +0200127 def test_parse_cert_CVE_2013_4238(self):
128 p = ssl._ssl._test_decode_cert(NULLBYTECERT)
129 if test_support.verbose:
130 sys.stdout.write("\n" + pprint.pformat(p) + "\n")
131 subject = ((('countryName', 'US'),),
132 (('stateOrProvinceName', 'Oregon'),),
133 (('localityName', 'Beaverton'),),
134 (('organizationName', 'Python Software Foundation'),),
135 (('organizationalUnitName', 'Python Core Development'),),
136 (('commonName', 'null.python.org\x00example.org'),),
137 (('emailAddress', 'python-dev@python.org'),))
138 self.assertEqual(p['subject'], subject)
139 self.assertEqual(p['issuer'], subject)
Christian Heimesa0c83732013-08-25 14:44:27 +0200140 if ssl.OPENSSL_VERSION_INFO >= (0, 9, 8):
Christian Heimesf869a942013-08-25 14:12:41 +0200141 san = (('DNS', 'altnull.python.org\x00example.com'),
142 ('email', 'null@python.org\x00user@example.org'),
143 ('URI', 'http://null.python.org\x00http://example.org'),
144 ('IP Address', '192.0.2.1'),
145 ('IP Address', '2001:DB8:0:0:0:0:0:1\n'))
146 else:
147 # OpenSSL 0.9.7 doesn't support IPv6 addresses in subjectAltName
148 san = (('DNS', 'altnull.python.org\x00example.com'),
149 ('email', 'null@python.org\x00user@example.org'),
150 ('URI', 'http://null.python.org\x00http://example.org'),
151 ('IP Address', '192.0.2.1'),
152 ('IP Address', '<invalid>'))
153
154 self.assertEqual(p['subjectAltName'], san)
Christian Heimes88b174c2013-08-17 00:54:47 +0200155
Antoine Pitrou3945c862010-04-28 21:11:01 +0000156 def test_DER_to_PEM(self):
157 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
158 pem = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +0000159 d1 = ssl.PEM_cert_to_DER_cert(pem)
160 p2 = ssl.DER_cert_to_PEM_cert(d1)
161 d2 = ssl.PEM_cert_to_DER_cert(p2)
Antoine Pitroudb187842010-04-27 10:32:58 +0000162 self.assertEqual(d1, d2)
Antoine Pitrou4c7bcf12010-04-27 22:03:37 +0000163 if not p2.startswith(ssl.PEM_HEADER + '\n'):
164 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
165 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
166 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
Bill Janssen296a59d2007-09-16 22:06:00 +0000167
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000168 def test_openssl_version(self):
169 n = ssl.OPENSSL_VERSION_NUMBER
170 t = ssl.OPENSSL_VERSION_INFO
171 s = ssl.OPENSSL_VERSION
172 self.assertIsInstance(n, (int, long))
173 self.assertIsInstance(t, tuple)
174 self.assertIsInstance(s, str)
175 # Some sanity checks follow
176 # >= 0.9
177 self.assertGreaterEqual(n, 0x900000)
178 # < 2.0
179 self.assertLess(n, 0x20000000)
180 major, minor, fix, patch, status = t
181 self.assertGreaterEqual(major, 0)
182 self.assertLess(major, 2)
183 self.assertGreaterEqual(minor, 0)
184 self.assertLess(minor, 256)
185 self.assertGreaterEqual(fix, 0)
186 self.assertLess(fix, 256)
187 self.assertGreaterEqual(patch, 0)
188 self.assertLessEqual(patch, 26)
189 self.assertGreaterEqual(status, 0)
190 self.assertLessEqual(status, 15)
191 # Version string as returned by OpenSSL, the format might change
192 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
193 (s, t))
194
Zachary Ware1f702212013-12-10 14:09:20 -0600195 @test_support.requires_resource('network')
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000196 def test_ciphers(self):
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000197 remote = ("svn.python.org", 443)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000198 with test_support.transient_internet(remote[0]):
199 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
200 cert_reqs=ssl.CERT_NONE, ciphers="ALL")
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000201 s.connect(remote)
Antoine Pitrou942d5542010-10-31 13:26:53 +0000202 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
203 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
204 s.connect(remote)
205 # Error checking occurs when connecting, because the SSL context
206 # isn't created before.
207 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
208 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
209 with self.assertRaisesRegexp(ssl.SSLError, "No cipher can be selected"):
210 s.connect(remote)
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000211
Antoine Pitroudfb299b2010-04-23 22:54:59 +0000212 @test_support.cpython_only
213 def test_refcycle(self):
214 # Issue #7943: an SSL object doesn't create reference cycles with
215 # itself.
216 s = socket.socket(socket.AF_INET)
217 ss = ssl.wrap_socket(s)
218 wr = weakref.ref(ss)
219 del ss
220 self.assertEqual(wr(), None)
221
Antoine Pitrouf7f390a2010-09-14 14:37:18 +0000222 def test_wrapped_unconnected(self):
223 # The _delegate_methods in socket.py are correctly delegated to by an
224 # unconnected SSLSocket, so they will raise a socket.error rather than
225 # something unexpected like TypeError.
226 s = socket.socket(socket.AF_INET)
227 ss = ssl.wrap_socket(s)
228 self.assertRaises(socket.error, ss.recv, 1)
229 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
230 self.assertRaises(socket.error, ss.recvfrom, 1)
231 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
232 self.assertRaises(socket.error, ss.send, b'x')
233 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
234
Antoine Pitrouf9de5342010-04-05 21:35:07 +0000235
Bill Janssen934b16d2008-06-28 22:19:33 +0000236class NetworkedTests(unittest.TestCase):
Bill Janssen296a59d2007-09-16 22:06:00 +0000237
Antoine Pitrou3945c862010-04-28 21:11:01 +0000238 def test_connect(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000239 with test_support.transient_internet("svn.python.org"):
240 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
241 cert_reqs=ssl.CERT_NONE)
Bill Janssen296a59d2007-09-16 22:06:00 +0000242 s.connect(("svn.python.org", 443))
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000243 c = s.getpeercert()
244 if c:
245 self.fail("Peer cert %s shouldn't be here!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000246 s.close()
247
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000248 # this should fail because we have no verification certs
249 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
250 cert_reqs=ssl.CERT_REQUIRED)
251 try:
252 s.connect(("svn.python.org", 443))
253 except ssl.SSLError:
254 pass
255 finally:
256 s.close()
257
258 # this should succeed because we specify the root cert
259 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
260 cert_reqs=ssl.CERT_REQUIRED,
261 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
262 try:
263 s.connect(("svn.python.org", 443))
264 finally:
265 s.close()
Bill Janssen296a59d2007-09-16 22:06:00 +0000266
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000267 def test_connect_ex(self):
268 # Issue #11326: check connect_ex() implementation
269 with test_support.transient_internet("svn.python.org"):
270 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
271 cert_reqs=ssl.CERT_REQUIRED,
272 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
273 try:
274 self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
275 self.assertTrue(s.getpeercert())
276 finally:
277 s.close()
278
279 def test_non_blocking_connect_ex(self):
280 # Issue #11326: non-blocking connect_ex() should allow handshake
281 # to proceed after the socket gets ready.
282 with test_support.transient_internet("svn.python.org"):
283 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
284 cert_reqs=ssl.CERT_REQUIRED,
285 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
286 do_handshake_on_connect=False)
287 try:
288 s.setblocking(False)
289 rc = s.connect_ex(('svn.python.org', 443))
Antoine Pitrou8ef39072011-02-27 15:45:22 +0000290 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
291 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
Antoine Pitroud3f6ea12011-02-26 23:35:27 +0000292 # Wait for connect to finish
293 select.select([], [s], [], 5.0)
294 # Non-blocking handshake
295 while True:
296 try:
297 s.do_handshake()
298 break
299 except ssl.SSLError as err:
300 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
301 select.select([s], [], [], 5.0)
302 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
303 select.select([], [s], [], 5.0)
304 else:
305 raise
306 # SSL established
307 self.assertTrue(s.getpeercert())
308 finally:
309 s.close()
310
Antoine Pitrou40f12ab2012-12-28 19:03:43 +0100311 def test_timeout_connect_ex(self):
312 # Issue #12065: on a timeout, connect_ex() should return the original
313 # errno (mimicking the behaviour of non-SSL sockets).
314 with test_support.transient_internet("svn.python.org"):
315 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
316 cert_reqs=ssl.CERT_REQUIRED,
317 ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
318 do_handshake_on_connect=False)
319 try:
320 s.settimeout(0.0000001)
321 rc = s.connect_ex(('svn.python.org', 443))
322 if rc == 0:
323 self.skipTest("svn.python.org responded too quickly")
324 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
325 finally:
326 s.close()
327
328 def test_connect_ex_error(self):
329 with test_support.transient_internet("svn.python.org"):
330 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
331 cert_reqs=ssl.CERT_REQUIRED,
332 ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
333 try:
334 self.assertEqual(errno.ECONNREFUSED,
335 s.connect_ex(("svn.python.org", 444)))
336 finally:
337 s.close()
338
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000339 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
340 def test_makefile_close(self):
341 # Issue #5238: creating a file-like object with makefile() shouldn't
342 # delay closing the underlying "real socket" (here tested with its
343 # file descriptor, hence skipping the test under Windows).
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000344 with test_support.transient_internet("svn.python.org"):
345 ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
346 ss.connect(("svn.python.org", 443))
347 fd = ss.fileno()
348 f = ss.makefile()
349 f.close()
350 # The fd is still open
Antoine Pitrou55841ac2010-04-24 10:43:57 +0000351 os.read(fd, 0)
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000352 # Closing the SSL socket should close the fd too
353 ss.close()
354 gc.collect()
355 with self.assertRaises(OSError) as e:
356 os.read(fd, 0)
357 self.assertEqual(e.exception.errno, errno.EBADF)
Bill Janssen934b16d2008-06-28 22:19:33 +0000358
Antoine Pitrou3945c862010-04-28 21:11:01 +0000359 def test_non_blocking_handshake(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000360 with test_support.transient_internet("svn.python.org"):
361 s = socket.socket(socket.AF_INET)
362 s.connect(("svn.python.org", 443))
363 s.setblocking(False)
364 s = ssl.wrap_socket(s,
365 cert_reqs=ssl.CERT_NONE,
366 do_handshake_on_connect=False)
367 count = 0
368 while True:
369 try:
370 count += 1
371 s.do_handshake()
372 break
373 except ssl.SSLError, err:
374 if err.args[0] == ssl.SSL_ERROR_WANT_READ:
375 select.select([s], [], [])
376 elif err.args[0] == ssl.SSL_ERROR_WANT_WRITE:
377 select.select([], [s], [])
378 else:
379 raise
380 s.close()
381 if test_support.verbose:
382 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
Bill Janssen934b16d2008-06-28 22:19:33 +0000383
Antoine Pitrou3945c862010-04-28 21:11:01 +0000384 def test_get_server_certificate(self):
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000385 with test_support.transient_internet("svn.python.org"):
386 pem = ssl.get_server_certificate(("svn.python.org", 443))
387 if not pem:
388 self.fail("No server certificate on svn.python.org:443!")
Bill Janssen296a59d2007-09-16 22:06:00 +0000389
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000390 try:
391 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=CERTFILE)
392 except ssl.SSLError:
393 #should fail
394 pass
395 else:
396 self.fail("Got server certificate %s for svn.python.org!" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000397
Antoine Pitrou4e406d82010-09-09 13:35:44 +0000398 pem = ssl.get_server_certificate(("svn.python.org", 443), ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
399 if not pem:
400 self.fail("No server certificate on svn.python.org:443!")
401 if test_support.verbose:
402 sys.stdout.write("\nVerified certificate for svn.python.org:443 is\n%s\n" % pem)
Bill Janssen296a59d2007-09-16 22:06:00 +0000403
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000404 def test_algorithms(self):
405 # Issue #8484: all algorithms should be available when verifying a
406 # certificate.
Antoine Pitrou9aed6042010-04-22 18:00:41 +0000407 # SHA256 was added in OpenSSL 0.9.8
408 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
409 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
Antoine Pitrouc642f672012-05-04 16:33:30 +0200410 self.skipTest("remote host needs SNI, only available on Python 3.2+")
411 # NOTE: https://sha2.hboeck.de is another possible test host
Antoine Pitroud43245a2011-01-08 10:32:51 +0000412 remote = ("sha256.tbs-internet.com", 443)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000413 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
Antoine Pitroud43245a2011-01-08 10:32:51 +0000414 with test_support.transient_internet("sha256.tbs-internet.com"):
Antoine Pitrouc818ed42010-09-07 21:40:25 +0000415 s = ssl.wrap_socket(socket.socket(socket.AF_INET),
416 cert_reqs=ssl.CERT_REQUIRED,
417 ca_certs=sha256_cert,)
Antoine Pitrouc715a9e2010-04-21 19:28:03 +0000418 try:
419 s.connect(remote)
420 if test_support.verbose:
421 sys.stdout.write("\nCipher with %r is %r\n" %
422 (remote, s.cipher()))
423 sys.stdout.write("Certificate is:\n%s\n" %
424 pprint.pformat(s.getpeercert()))
425 finally:
426 s.close()
427
Bill Janssen296a59d2007-09-16 22:06:00 +0000428
Bill Janssen98d19da2007-09-10 21:51:02 +0000429try:
430 import threading
431except ImportError:
432 _have_threads = False
433else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000434 _have_threads = True
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000435
Bill Janssen98d19da2007-09-10 21:51:02 +0000436 class ThreadedEchoServer(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000437
Bill Janssen98d19da2007-09-10 21:51:02 +0000438 class ConnectionHandler(threading.Thread):
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000439
Bill Janssen98d19da2007-09-10 21:51:02 +0000440 """A mildly complicated class, because we want it to work both
441 with and without the SSL wrapper around the socket connection, so
442 that we can test the STARTTLS functionality."""
443
444 def __init__(self, server, connsock):
445 self.server = server
446 self.running = False
447 self.sock = connsock
448 self.sock.setblocking(1)
449 self.sslconn = None
450 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000451 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000452
Bill Janssen934b16d2008-06-28 22:19:33 +0000453 def show_conn_details(self):
454 if self.server.certreqs == ssl.CERT_REQUIRED:
455 cert = self.sslconn.getpeercert()
456 if test_support.verbose and self.server.chatty:
457 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
458 cert_binary = self.sslconn.getpeercert(True)
459 if test_support.verbose and self.server.chatty:
460 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
461 cipher = self.sslconn.cipher()
462 if test_support.verbose and self.server.chatty:
463 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
464
Antoine Pitrou3945c862010-04-28 21:11:01 +0000465 def wrap_conn(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000466 try:
467 self.sslconn = ssl.wrap_socket(self.sock, server_side=True,
468 certfile=self.server.certificate,
469 ssl_version=self.server.protocol,
470 ca_certs=self.server.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000471 cert_reqs=self.server.certreqs,
472 ciphers=self.server.ciphers)
Antoine Pitroud76088d2012-01-03 22:46:48 +0100473 except ssl.SSLError as e:
Antoine Pitroudb187842010-04-27 10:32:58 +0000474 # XXX Various errors can have happened here, for example
475 # a mismatching protocol version, an invalid certificate,
476 # or a low-level bug. This should be made more discriminating.
Antoine Pitroud76088d2012-01-03 22:46:48 +0100477 self.server.conn_errors.append(e)
Bill Janssen98d19da2007-09-10 21:51:02 +0000478 if self.server.chatty:
479 handle_error("\n server: bad connection attempt from " +
480 str(self.sock.getpeername()) + ":\n")
Bill Janssen934b16d2008-06-28 22:19:33 +0000481 self.close()
Antoine Pitroudb187842010-04-27 10:32:58 +0000482 self.running = False
483 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000484 return False
Bill Janssen98d19da2007-09-10 21:51:02 +0000485 else:
Bill Janssen98d19da2007-09-10 21:51:02 +0000486 return True
487
488 def read(self):
489 if self.sslconn:
490 return self.sslconn.read()
491 else:
492 return self.sock.recv(1024)
493
494 def write(self, bytes):
495 if self.sslconn:
496 return self.sslconn.write(bytes)
497 else:
498 return self.sock.send(bytes)
499
500 def close(self):
501 if self.sslconn:
502 self.sslconn.close()
503 else:
Bill Janssen934b16d2008-06-28 22:19:33 +0000504 self.sock._sock.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000505
Antoine Pitrou3945c862010-04-28 21:11:01 +0000506 def run(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000507 self.running = True
508 if not self.server.starttls_server:
Bill Janssen934b16d2008-06-28 22:19:33 +0000509 if isinstance(self.sock, ssl.SSLSocket):
510 self.sslconn = self.sock
511 elif not self.wrap_conn():
Bill Janssen98d19da2007-09-10 21:51:02 +0000512 return
Bill Janssen934b16d2008-06-28 22:19:33 +0000513 self.show_conn_details()
Bill Janssen98d19da2007-09-10 21:51:02 +0000514 while self.running:
515 try:
516 msg = self.read()
517 if not msg:
518 # eof, so quit this handler
519 self.running = False
520 self.close()
521 elif msg.strip() == 'over':
522 if test_support.verbose and self.server.connectionchatty:
523 sys.stdout.write(" server: client closed connection\n")
524 self.close()
525 return
526 elif self.server.starttls_server and msg.strip() == 'STARTTLS':
527 if test_support.verbose and self.server.connectionchatty:
528 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
529 self.write("OK\n")
530 if not self.wrap_conn():
531 return
Bill Janssen39295c22008-08-12 16:31:21 +0000532 elif self.server.starttls_server and self.sslconn and msg.strip() == 'ENDTLS':
533 if test_support.verbose and self.server.connectionchatty:
534 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
535 self.write("OK\n")
536 self.sslconn.unwrap()
537 self.sslconn = None
538 if test_support.verbose and self.server.connectionchatty:
539 sys.stdout.write(" server: connection is now unencrypted...\n")
Bill Janssen98d19da2007-09-10 21:51:02 +0000540 else:
541 if (test_support.verbose and
542 self.server.connectionchatty):
543 ctype = (self.sslconn and "encrypted") or "unencrypted"
544 sys.stdout.write(" server: read %s (%s), sending back %s (%s)...\n"
545 % (repr(msg), ctype, repr(msg.lower()), ctype))
546 self.write(msg.lower())
547 except ssl.SSLError:
548 if self.server.chatty:
549 handle_error("Test server failure:\n")
550 self.close()
551 self.running = False
552 # normally, we'd just stop here, but for the test
553 # harness, we want to stop the server
554 self.server.stop()
Bill Janssen98d19da2007-09-10 21:51:02 +0000555
Trent Nelsone41b0062008-04-08 23:47:30 +0000556 def __init__(self, certificate, ssl_version=None,
Antoine Pitroudb187842010-04-27 10:32:58 +0000557 certreqs=None, cacerts=None,
Bill Janssen934b16d2008-06-28 22:19:33 +0000558 chatty=True, connectionchatty=False, starttls_server=False,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000559 wrap_accepting_socket=False, ciphers=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000560
Bill Janssen98d19da2007-09-10 21:51:02 +0000561 if ssl_version is None:
562 ssl_version = ssl.PROTOCOL_TLSv1
563 if certreqs is None:
564 certreqs = ssl.CERT_NONE
565 self.certificate = certificate
566 self.protocol = ssl_version
567 self.certreqs = certreqs
568 self.cacerts = cacerts
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000569 self.ciphers = ciphers
Bill Janssen98d19da2007-09-10 21:51:02 +0000570 self.chatty = chatty
571 self.connectionchatty = connectionchatty
572 self.starttls_server = starttls_server
573 self.sock = socket.socket()
574 self.flag = None
Bill Janssen934b16d2008-06-28 22:19:33 +0000575 if wrap_accepting_socket:
576 self.sock = ssl.wrap_socket(self.sock, server_side=True,
577 certfile=self.certificate,
578 cert_reqs = self.certreqs,
579 ca_certs = self.cacerts,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000580 ssl_version = self.protocol,
581 ciphers = self.ciphers)
Bill Janssen934b16d2008-06-28 22:19:33 +0000582 if test_support.verbose and self.chatty:
583 sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
584 self.port = test_support.bind_port(self.sock)
Bill Janssen98d19da2007-09-10 21:51:02 +0000585 self.active = False
Antoine Pitroud76088d2012-01-03 22:46:48 +0100586 self.conn_errors = []
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000587 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000588 self.daemon = True
Bill Janssen98d19da2007-09-10 21:51:02 +0000589
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100590 def __enter__(self):
591 self.start(threading.Event())
592 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100593 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100594
595 def __exit__(self, *args):
596 self.stop()
597 self.join()
598
Antoine Pitrou3945c862010-04-28 21:11:01 +0000599 def start(self, flag=None):
Bill Janssen98d19da2007-09-10 21:51:02 +0000600 self.flag = flag
601 threading.Thread.start(self)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000602
Antoine Pitrou3945c862010-04-28 21:11:01 +0000603 def run(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000604 self.sock.settimeout(0.05)
Bill Janssen98d19da2007-09-10 21:51:02 +0000605 self.sock.listen(5)
606 self.active = True
607 if self.flag:
608 # signal an event
609 self.flag.set()
610 while self.active:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000611 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000612 newconn, connaddr = self.sock.accept()
613 if test_support.verbose and self.chatty:
614 sys.stdout.write(' server: new connection from '
615 + str(connaddr) + '\n')
616 handler = self.ConnectionHandler(self, newconn)
617 handler.start()
Antoine Pitrou7a556842012-01-27 17:33:01 +0100618 handler.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000619 except socket.timeout:
620 pass
621 except KeyboardInterrupt:
622 self.stop()
Bill Janssen934b16d2008-06-28 22:19:33 +0000623 self.sock.close()
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000624
Antoine Pitrou3945c862010-04-28 21:11:01 +0000625 def stop(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000626 self.active = False
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000627
Bill Janssen934b16d2008-06-28 22:19:33 +0000628 class AsyncoreEchoServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000629
Antoine Pitrou3945c862010-04-28 21:11:01 +0000630 class EchoServer(asyncore.dispatcher):
Bill Janssen934b16d2008-06-28 22:19:33 +0000631
Antoine Pitrou3945c862010-04-28 21:11:01 +0000632 class ConnectionHandler(asyncore.dispatcher_with_send):
Bill Janssen934b16d2008-06-28 22:19:33 +0000633
634 def __init__(self, conn, certfile):
635 asyncore.dispatcher_with_send.__init__(self, conn)
636 self.socket = ssl.wrap_socket(conn, server_side=True,
637 certfile=certfile,
Antoine Pitroufc69af12010-04-24 20:04:58 +0000638 do_handshake_on_connect=False)
639 self._ssl_accepting = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000640
641 def readable(self):
642 if isinstance(self.socket, ssl.SSLSocket):
643 while self.socket.pending() > 0:
644 self.handle_read_event()
645 return True
646
Antoine Pitroufc69af12010-04-24 20:04:58 +0000647 def _do_ssl_handshake(self):
648 try:
649 self.socket.do_handshake()
650 except ssl.SSLError, err:
651 if err.args[0] in (ssl.SSL_ERROR_WANT_READ,
652 ssl.SSL_ERROR_WANT_WRITE):
653 return
654 elif err.args[0] == ssl.SSL_ERROR_EOF:
655 return self.handle_close()
656 raise
657 except socket.error, err:
658 if err.args[0] == errno.ECONNABORTED:
659 return self.handle_close()
660 else:
661 self._ssl_accepting = False
662
Bill Janssen934b16d2008-06-28 22:19:33 +0000663 def handle_read(self):
Antoine Pitroufc69af12010-04-24 20:04:58 +0000664 if self._ssl_accepting:
665 self._do_ssl_handshake()
666 else:
667 data = self.recv(1024)
Antoine Pitroudb187842010-04-27 10:32:58 +0000668 if data and data.strip() != 'over':
669 self.send(data.lower())
Bill Janssen934b16d2008-06-28 22:19:33 +0000670
671 def handle_close(self):
Bill Janssende34d912008-06-28 23:00:39 +0000672 self.close()
Bill Janssen934b16d2008-06-28 22:19:33 +0000673 if test_support.verbose:
674 sys.stdout.write(" server: closed connection %s\n" % self.socket)
675
676 def handle_error(self):
677 raise
678
679 def __init__(self, certfile):
680 self.certfile = certfile
681 asyncore.dispatcher.__init__(self)
682 self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
683 self.port = test_support.bind_port(self.socket)
684 self.listen(5)
685
686 def handle_accept(self):
687 sock_obj, addr = self.accept()
688 if test_support.verbose:
689 sys.stdout.write(" server: new connection from %s:%s\n" %addr)
690 self.ConnectionHandler(sock_obj, self.certfile)
691
692 def handle_error(self):
693 raise
694
695 def __init__(self, certfile):
696 self.flag = None
697 self.active = False
698 self.server = self.EchoServer(certfile)
699 self.port = self.server.port
700 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000701 self.daemon = True
Bill Janssen934b16d2008-06-28 22:19:33 +0000702
703 def __str__(self):
704 return "<%s %s>" % (self.__class__.__name__, self.server)
705
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100706 def __enter__(self):
707 self.start(threading.Event())
708 self.flag.wait()
Antoine Pitroud76088d2012-01-03 22:46:48 +0100709 return self
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100710
711 def __exit__(self, *args):
712 if test_support.verbose:
713 sys.stdout.write(" cleanup: stopping server.\n")
714 self.stop()
715 if test_support.verbose:
716 sys.stdout.write(" cleanup: joining server thread.\n")
717 self.join()
718 if test_support.verbose:
719 sys.stdout.write(" cleanup: successfully joined.\n")
720
Antoine Pitrou3945c862010-04-28 21:11:01 +0000721 def start(self, flag=None):
Bill Janssen934b16d2008-06-28 22:19:33 +0000722 self.flag = flag
723 threading.Thread.start(self)
724
Antoine Pitrou3945c862010-04-28 21:11:01 +0000725 def run(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000726 self.active = True
727 if self.flag:
728 self.flag.set()
729 while self.active:
Antoine Pitroudb187842010-04-27 10:32:58 +0000730 asyncore.loop(0.05)
Bill Janssen934b16d2008-06-28 22:19:33 +0000731
Antoine Pitrou3945c862010-04-28 21:11:01 +0000732 def stop(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000733 self.active = False
734 self.server.close()
735
736 class SocketServerHTTPSServer(threading.Thread):
Bill Janssen296a59d2007-09-16 22:06:00 +0000737
738 class HTTPSServer(HTTPServer):
739
740 def __init__(self, server_address, RequestHandlerClass, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000741 HTTPServer.__init__(self, server_address, RequestHandlerClass)
742 # we assume the certfile contains both private key and certificate
743 self.certfile = certfile
Bill Janssen296a59d2007-09-16 22:06:00 +0000744 self.allow_reuse_address = True
745
Bill Janssen934b16d2008-06-28 22:19:33 +0000746 def __str__(self):
747 return ('<%s %s:%s>' %
748 (self.__class__.__name__,
749 self.server_name,
750 self.server_port))
751
Antoine Pitrou3945c862010-04-28 21:11:01 +0000752 def get_request(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000753 # override this to wrap socket with SSL
754 sock, addr = self.socket.accept()
755 sslconn = ssl.wrap_socket(sock, server_side=True,
756 certfile=self.certfile)
757 return sslconn, addr
758
Bill Janssen296a59d2007-09-16 22:06:00 +0000759 class RootedHTTPRequestHandler(SimpleHTTPRequestHandler):
Bill Janssen296a59d2007-09-16 22:06:00 +0000760 # need to override translate_path to get a known root,
761 # instead of using os.curdir, since the test could be
762 # run from anywhere
763
764 server_version = "TestHTTPS/1.0"
765
766 root = None
767
768 def translate_path(self, path):
769 """Translate a /-separated PATH to the local filename syntax.
770
771 Components that mean special things to the local file system
772 (e.g. drive or directory names) are ignored. (XXX They should
773 probably be diagnosed.)
774
775 """
776 # abandon query parameters
777 path = urlparse.urlparse(path)[2]
778 path = os.path.normpath(urllib.unquote(path))
779 words = path.split('/')
780 words = filter(None, words)
781 path = self.root
782 for word in words:
783 drive, word = os.path.splitdrive(word)
784 head, word = os.path.split(word)
785 if word in self.root: continue
786 path = os.path.join(path, word)
787 return path
788
789 def log_message(self, format, *args):
790
791 # we override this to suppress logging unless "verbose"
792
793 if test_support.verbose:
Bill Janssen934b16d2008-06-28 22:19:33 +0000794 sys.stdout.write(" server (%s:%d %s):\n [%s] %s\n" %
795 (self.server.server_address,
Bill Janssen296a59d2007-09-16 22:06:00 +0000796 self.server.server_port,
797 self.request.cipher(),
798 self.log_date_time_string(),
799 format%args))
800
801
Trent Nelsone41b0062008-04-08 23:47:30 +0000802 def __init__(self, certfile):
Bill Janssen296a59d2007-09-16 22:06:00 +0000803 self.flag = None
Bill Janssen296a59d2007-09-16 22:06:00 +0000804 self.RootedHTTPRequestHandler.root = os.path.split(CERTFILE)[0]
805 self.server = self.HTTPSServer(
Antoine Pitrou150acda2010-04-27 08:40:51 +0000806 (HOST, 0), self.RootedHTTPRequestHandler, certfile)
807 self.port = self.server.server_port
Bill Janssen296a59d2007-09-16 22:06:00 +0000808 threading.Thread.__init__(self)
Benjamin Peterson26f52162008-08-18 18:39:57 +0000809 self.daemon = True
Bill Janssen296a59d2007-09-16 22:06:00 +0000810
811 def __str__(self):
Bill Janssen934b16d2008-06-28 22:19:33 +0000812 return "<%s %s>" % (self.__class__.__name__, self.server)
Bill Janssen296a59d2007-09-16 22:06:00 +0000813
Antoine Pitrou3945c862010-04-28 21:11:01 +0000814 def start(self, flag=None):
Bill Janssen296a59d2007-09-16 22:06:00 +0000815 self.flag = flag
816 threading.Thread.start(self)
817
Antoine Pitrou3945c862010-04-28 21:11:01 +0000818 def run(self):
Bill Janssen296a59d2007-09-16 22:06:00 +0000819 if self.flag:
820 self.flag.set()
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000821 self.server.serve_forever(0.05)
Bill Janssen296a59d2007-09-16 22:06:00 +0000822
Antoine Pitrou3945c862010-04-28 21:11:01 +0000823 def stop(self):
Antoine Pitrou435ba0c2010-04-27 09:51:18 +0000824 self.server.shutdown()
Bill Janssen296a59d2007-09-16 22:06:00 +0000825
826
Antoine Pitrou3945c862010-04-28 21:11:01 +0000827 def bad_cert_test(certfile):
828 """
829 Launch a server with CERT_REQUIRED, and check that trying to
830 connect to it with the given client certificate fails.
831 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000832 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000833 certreqs=ssl.CERT_REQUIRED,
834 cacerts=CERTFILE, chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100835 with server:
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000836 try:
Bill Janssen98d19da2007-09-10 21:51:02 +0000837 s = ssl.wrap_socket(socket.socket(),
838 certfile=certfile,
839 ssl_version=ssl.PROTOCOL_TLSv1)
Trent Nelsone41b0062008-04-08 23:47:30 +0000840 s.connect((HOST, server.port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000841 except ssl.SSLError, x:
Neal Norwitz9eb9b102007-08-27 01:15:33 +0000842 if test_support.verbose:
Bill Janssen98d19da2007-09-10 21:51:02 +0000843 sys.stdout.write("\nSSLError is %s\n" % x[1])
Antoine Pitrou9bf54252010-04-27 13:13:26 +0000844 except socket.error, x:
845 if test_support.verbose:
846 sys.stdout.write("\nsocket.error is %s\n" % x[1])
Bill Janssen98d19da2007-09-10 21:51:02 +0000847 else:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000848 raise AssertionError("Use of invalid cert should have failed!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +0000849
Antoine Pitrou3945c862010-04-28 21:11:01 +0000850 def server_params_test(certfile, protocol, certreqs, cacertsfile,
851 client_certfile, client_protocol=None, indata="FOO\n",
852 ciphers=None, chatty=True, connectionchatty=False,
853 wrap_accepting_socket=False):
854 """
855 Launch a server, connect a client to it and try various reads
856 and writes.
857 """
Trent Nelsone41b0062008-04-08 23:47:30 +0000858 server = ThreadedEchoServer(certfile,
Bill Janssen98d19da2007-09-10 21:51:02 +0000859 certreqs=certreqs,
860 ssl_version=protocol,
861 cacerts=cacertsfile,
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000862 ciphers=ciphers,
Bill Janssen98d19da2007-09-10 21:51:02 +0000863 chatty=chatty,
Bill Janssen934b16d2008-06-28 22:19:33 +0000864 connectionchatty=connectionchatty,
865 wrap_accepting_socket=wrap_accepting_socket)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100866 with server:
867 # try to connect
868 if client_protocol is None:
869 client_protocol = protocol
Antoine Pitroudb187842010-04-27 10:32:58 +0000870 s = ssl.wrap_socket(socket.socket(),
871 certfile=client_certfile,
872 ca_certs=cacertsfile,
873 ciphers=ciphers,
874 cert_reqs=certreqs,
875 ssl_version=client_protocol)
876 s.connect((HOST, server.port))
877 for arg in [indata, bytearray(indata), memoryview(indata)]:
Bill Janssen98d19da2007-09-10 21:51:02 +0000878 if connectionchatty:
879 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +0000880 sys.stdout.write(
881 " client: sending %s...\n" % (repr(arg)))
882 s.write(arg)
883 outdata = s.read()
884 if connectionchatty:
885 if test_support.verbose:
886 sys.stdout.write(" client: read %s\n" % repr(outdata))
887 if outdata != indata.lower():
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000888 raise AssertionError(
Antoine Pitroudb187842010-04-27 10:32:58 +0000889 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
890 % (outdata[:min(len(outdata),20)], len(outdata),
891 indata[:min(len(indata),20)].lower(), len(indata)))
892 s.write("over\n")
893 if connectionchatty:
894 if test_support.verbose:
895 sys.stdout.write(" client: closing connection.\n")
896 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000897
Antoine Pitrou3945c862010-04-28 21:11:01 +0000898 def try_protocol_combo(server_protocol,
899 client_protocol,
900 expect_success,
901 certsreqs=None):
Benjamin Peterson5b63acd2008-03-29 15:24:25 +0000902 if certsreqs is None:
Bill Janssene3f1d7d2007-09-11 01:09:19 +0000903 certsreqs = ssl.CERT_NONE
Antoine Pitrou3945c862010-04-28 21:11:01 +0000904 certtype = {
905 ssl.CERT_NONE: "CERT_NONE",
906 ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
907 ssl.CERT_REQUIRED: "CERT_REQUIRED",
908 }[certsreqs]
Bill Janssen98d19da2007-09-10 21:51:02 +0000909 if test_support.verbose:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000910 formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
Bill Janssen98d19da2007-09-10 21:51:02 +0000911 sys.stdout.write(formatstr %
912 (ssl.get_protocol_name(client_protocol),
913 ssl.get_protocol_name(server_protocol),
914 certtype))
915 try:
Antoine Pitrou0a6373c2010-04-17 17:10:38 +0000916 # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
917 # will send an SSLv3 hello (rather than SSLv2) starting from
918 # OpenSSL 1.0.0 (see issue #8322).
Antoine Pitrou3945c862010-04-28 21:11:01 +0000919 server_params_test(CERTFILE, server_protocol, certsreqs,
920 CERTFILE, CERTFILE, client_protocol,
921 ciphers="ALL", chatty=False)
Antoine Pitroudb187842010-04-27 10:32:58 +0000922 # Protocol mismatch can result in either an SSLError, or a
923 # "Connection reset by peer" error.
924 except ssl.SSLError:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000925 if expect_success:
Bill Janssen98d19da2007-09-10 21:51:02 +0000926 raise
Antoine Pitroudb187842010-04-27 10:32:58 +0000927 except socket.error as e:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000928 if expect_success or e.errno != errno.ECONNRESET:
Antoine Pitroudb187842010-04-27 10:32:58 +0000929 raise
Bill Janssen98d19da2007-09-10 21:51:02 +0000930 else:
Antoine Pitrou3945c862010-04-28 21:11:01 +0000931 if not expect_success:
Antoine Pitrou1bbb68d2010-05-06 14:11:23 +0000932 raise AssertionError(
Bill Janssen98d19da2007-09-10 21:51:02 +0000933 "Client protocol %s succeeded with server protocol %s!"
934 % (ssl.get_protocol_name(client_protocol),
935 ssl.get_protocol_name(server_protocol)))
936
937
Bill Janssen934b16d2008-06-28 22:19:33 +0000938 class ThreadedTests(unittest.TestCase):
Bill Janssen98d19da2007-09-10 21:51:02 +0000939
Antoine Pitrou3945c862010-04-28 21:11:01 +0000940 def test_rude_shutdown(self):
941 """A brutal shutdown of an SSL server should raise an IOError
942 in the client when attempting handshake.
943 """
Bill Janssen98d19da2007-09-10 21:51:02 +0000944 listener_ready = threading.Event()
945 listener_gone = threading.Event()
946
Antoine Pitrou150acda2010-04-27 08:40:51 +0000947 s = socket.socket()
948 port = test_support.bind_port(s, HOST)
949
950 # `listener` runs in a thread. It sits in an accept() until
951 # the main thread connects. Then it rudely closes the socket,
952 # and sets Event `listener_gone` to let the main thread know
953 # the socket is gone.
Bill Janssen98d19da2007-09-10 21:51:02 +0000954 def listener():
Bill Janssen98d19da2007-09-10 21:51:02 +0000955 s.listen(5)
956 listener_ready.set()
957 s.accept()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000958 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +0000959 listener_gone.set()
960
961 def connector():
962 listener_ready.wait()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000963 c = socket.socket()
964 c.connect((HOST, port))
Bill Janssen98d19da2007-09-10 21:51:02 +0000965 listener_gone.wait()
966 try:
Antoine Pitrou150acda2010-04-27 08:40:51 +0000967 ssl_sock = ssl.wrap_socket(c)
Bill Janssen934b16d2008-06-28 22:19:33 +0000968 except IOError:
Bill Janssen98d19da2007-09-10 21:51:02 +0000969 pass
970 else:
Antoine Pitroudb187842010-04-27 10:32:58 +0000971 self.fail('connecting to closed SSL socket should have failed')
Bill Janssen98d19da2007-09-10 21:51:02 +0000972
973 t = threading.Thread(target=listener)
974 t.start()
Antoine Pitrou150acda2010-04-27 08:40:51 +0000975 try:
976 connector()
977 finally:
978 t.join()
Bill Janssen98d19da2007-09-10 21:51:02 +0000979
Antoine Pitroud75efd92010-08-04 17:38:33 +0000980 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +0000981 def test_echo(self):
982 """Basic test of an SSL client connecting to a server"""
Bill Janssen98d19da2007-09-10 21:51:02 +0000983 if test_support.verbose:
984 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +0000985 server_params_test(CERTFILE, ssl.PROTOCOL_TLSv1, ssl.CERT_NONE,
986 CERTFILE, CERTFILE, ssl.PROTOCOL_TLSv1,
987 chatty=True, connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +0000988
Antoine Pitrou3945c862010-04-28 21:11:01 +0000989 def test_getpeercert(self):
Bill Janssen98d19da2007-09-10 21:51:02 +0000990 if test_support.verbose:
991 sys.stdout.write("\n")
992 s2 = socket.socket()
Trent Nelsone41b0062008-04-08 23:47:30 +0000993 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +0000994 certreqs=ssl.CERT_NONE,
995 ssl_version=ssl.PROTOCOL_SSLv23,
996 cacerts=CERTFILE,
997 chatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +0100998 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +0000999 s = ssl.wrap_socket(socket.socket(),
1000 certfile=CERTFILE,
1001 ca_certs=CERTFILE,
1002 cert_reqs=ssl.CERT_REQUIRED,
1003 ssl_version=ssl.PROTOCOL_SSLv23)
1004 s.connect((HOST, server.port))
1005 cert = s.getpeercert()
1006 self.assertTrue(cert, "Can't get peer certificate.")
1007 cipher = s.cipher()
1008 if test_support.verbose:
1009 sys.stdout.write(pprint.pformat(cert) + '\n')
1010 sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1011 if 'subject' not in cert:
1012 self.fail("No subject field in certificate: %s." %
1013 pprint.pformat(cert))
1014 if ((('organizationName', 'Python Software Foundation'),)
1015 not in cert['subject']):
1016 self.fail(
1017 "Missing or invalid 'organizationName' field in certificate subject; "
1018 "should be 'Python Software Foundation'.")
1019 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001020
Antoine Pitrou3945c862010-04-28 21:11:01 +00001021 def test_empty_cert(self):
1022 """Connecting with an empty cert file"""
1023 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1024 "nullcert.pem"))
1025 def test_malformed_cert(self):
1026 """Connecting with a badly formatted certificate (syntax error)"""
1027 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1028 "badcert.pem"))
1029 def test_nonexisting_cert(self):
1030 """Connecting with a non-existing cert file"""
1031 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1032 "wrongcert.pem"))
1033 def test_malformed_key(self):
1034 """Connecting with a badly formatted key (syntax error)"""
1035 bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1036 "badkey.pem"))
Bill Janssen98d19da2007-09-10 21:51:02 +00001037
Antoine Pitroud75efd92010-08-04 17:38:33 +00001038 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001039 def test_protocol_sslv2(self):
1040 """Connecting to an SSLv2 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001041 if test_support.verbose:
1042 sys.stdout.write("\n")
Antoine Pitrou6361ea22011-10-30 21:31:34 +01001043 if not hasattr(ssl, 'PROTOCOL_SSLv2'):
1044 self.skipTest("PROTOCOL_SSLv2 needed")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001045 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1046 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1047 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1048 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1049 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1050 try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001051
Antoine Pitroud75efd92010-08-04 17:38:33 +00001052 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001053 def test_protocol_sslv23(self):
1054 """Connecting to an SSLv23 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001055 if test_support.verbose:
1056 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001057 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1058 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1059 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001060
Antoine Pitrou3945c862010-04-28 21:11:01 +00001061 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1062 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1063 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
Bill Janssen98d19da2007-09-10 21:51:02 +00001064
Antoine Pitrou3945c862010-04-28 21:11:01 +00001065 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1066 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1067 try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Bill Janssen98d19da2007-09-10 21:51:02 +00001068
Antoine Pitroud75efd92010-08-04 17:38:33 +00001069 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001070 def test_protocol_sslv3(self):
1071 """Connecting to an SSLv3 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001072 if test_support.verbose:
1073 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001074 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1075 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1076 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001077 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1078 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001079 try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001080
Antoine Pitroud75efd92010-08-04 17:38:33 +00001081 @skip_if_broken_ubuntu_ssl
Antoine Pitrou3945c862010-04-28 21:11:01 +00001082 def test_protocol_tlsv1(self):
1083 """Connecting to a TLSv1 server with various client options"""
Bill Janssen98d19da2007-09-10 21:51:02 +00001084 if test_support.verbose:
1085 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001086 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1087 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1088 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
Victor Stinnerb1241f92011-05-10 01:52:03 +02001089 if hasattr(ssl, 'PROTOCOL_SSLv2'):
1090 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
Antoine Pitrou3945c862010-04-28 21:11:01 +00001091 try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
Bill Janssen98d19da2007-09-10 21:51:02 +00001092
Antoine Pitrou3945c862010-04-28 21:11:01 +00001093 def test_starttls(self):
1094 """Switching from clear text to encrypted and back again."""
Bill Janssen39295c22008-08-12 16:31:21 +00001095 msgs = ("msg 1", "MSG 2", "STARTTLS", "MSG 3", "msg 4", "ENDTLS", "msg 5", "msg 6")
Bill Janssen98d19da2007-09-10 21:51:02 +00001096
Trent Nelsone41b0062008-04-08 23:47:30 +00001097 server = ThreadedEchoServer(CERTFILE,
Bill Janssen98d19da2007-09-10 21:51:02 +00001098 ssl_version=ssl.PROTOCOL_TLSv1,
1099 starttls_server=True,
1100 chatty=True,
1101 connectionchatty=True)
Bill Janssen98d19da2007-09-10 21:51:02 +00001102 wrapped = False
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001103 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001104 s = socket.socket()
1105 s.setblocking(1)
1106 s.connect((HOST, server.port))
1107 if test_support.verbose:
1108 sys.stdout.write("\n")
1109 for indata in msgs:
Bill Janssen98d19da2007-09-10 21:51:02 +00001110 if test_support.verbose:
Antoine Pitroudb187842010-04-27 10:32:58 +00001111 sys.stdout.write(
1112 " client: sending %s...\n" % repr(indata))
1113 if wrapped:
1114 conn.write(indata)
1115 outdata = conn.read()
1116 else:
1117 s.send(indata)
1118 outdata = s.recv(1024)
1119 if (indata == "STARTTLS" and
1120 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001121 # STARTTLS ok, switch to secure mode
Bill Janssen98d19da2007-09-10 21:51:02 +00001122 if test_support.verbose:
Bill Janssen296a59d2007-09-16 22:06:00 +00001123 sys.stdout.write(
Antoine Pitroudb187842010-04-27 10:32:58 +00001124 " client: read %s from server, starting TLS...\n"
1125 % repr(outdata))
1126 conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1127 wrapped = True
1128 elif (indata == "ENDTLS" and
1129 outdata.strip().lower().startswith("ok")):
Antoine Pitrou3945c862010-04-28 21:11:01 +00001130 # ENDTLS ok, switch back to clear text
Antoine Pitroudb187842010-04-27 10:32:58 +00001131 if test_support.verbose:
1132 sys.stdout.write(
1133 " client: read %s from server, ending TLS...\n"
1134 % repr(outdata))
1135 s = conn.unwrap()
1136 wrapped = False
Bill Janssen98d19da2007-09-10 21:51:02 +00001137 else:
Antoine Pitroudb187842010-04-27 10:32:58 +00001138 if test_support.verbose:
1139 sys.stdout.write(
1140 " client: read %s from server\n" % repr(outdata))
1141 if test_support.verbose:
1142 sys.stdout.write(" client: closing connection.\n")
1143 if wrapped:
1144 conn.write("over\n")
1145 else:
1146 s.send("over\n")
1147 s.close()
Bill Janssen98d19da2007-09-10 21:51:02 +00001148
Antoine Pitrou3945c862010-04-28 21:11:01 +00001149 def test_socketserver(self):
1150 """Using a SocketServer to create and manage SSL connections."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001151 server = SocketServerHTTPSServer(CERTFILE)
Bill Janssen296a59d2007-09-16 22:06:00 +00001152 flag = threading.Event()
1153 server.start(flag)
1154 # wait for it to start
1155 flag.wait()
1156 # try to connect
1157 try:
1158 if test_support.verbose:
1159 sys.stdout.write('\n')
Antoine Pitrou3945c862010-04-28 21:11:01 +00001160 with open(CERTFILE, 'rb') as f:
1161 d1 = f.read()
Bill Janssen296a59d2007-09-16 22:06:00 +00001162 d2 = ''
1163 # now fetch the same data from the HTTPS server
Bill Janssen934b16d2008-06-28 22:19:33 +00001164 url = 'https://127.0.0.1:%d/%s' % (
1165 server.port, os.path.split(CERTFILE)[1])
Florent Xicluna07627882010-03-21 01:14:24 +00001166 with test_support.check_py3k_warnings():
1167 f = urllib.urlopen(url)
Bill Janssen296a59d2007-09-16 22:06:00 +00001168 dlen = f.info().getheader("content-length")
1169 if dlen and (int(dlen) > 0):
1170 d2 = f.read(int(dlen))
1171 if test_support.verbose:
1172 sys.stdout.write(
1173 " client: read %d bytes from remote server '%s'\n"
1174 % (len(d2), server))
1175 f.close()
Antoine Pitroudb187842010-04-27 10:32:58 +00001176 self.assertEqual(d1, d2)
Bill Janssen296a59d2007-09-16 22:06:00 +00001177 finally:
1178 server.stop()
1179 server.join()
Neal Norwitz7fc8e292007-08-26 18:50:39 +00001180
Antoine Pitrou3945c862010-04-28 21:11:01 +00001181 def test_wrapped_accept(self):
1182 """Check the accept() method on SSL sockets."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001183 if test_support.verbose:
1184 sys.stdout.write("\n")
Antoine Pitrou3945c862010-04-28 21:11:01 +00001185 server_params_test(CERTFILE, ssl.PROTOCOL_SSLv23, ssl.CERT_REQUIRED,
1186 CERTFILE, CERTFILE, ssl.PROTOCOL_SSLv23,
1187 chatty=True, connectionchatty=True,
1188 wrap_accepting_socket=True)
Bill Janssen934b16d2008-06-28 22:19:33 +00001189
Antoine Pitrou3945c862010-04-28 21:11:01 +00001190 def test_asyncore_server(self):
1191 """Check the example asyncore integration."""
Bill Janssen934b16d2008-06-28 22:19:33 +00001192 indata = "TEST MESSAGE of mixed case\n"
1193
1194 if test_support.verbose:
1195 sys.stdout.write("\n")
1196 server = AsyncoreEchoServer(CERTFILE)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001197 with server:
Antoine Pitroudb187842010-04-27 10:32:58 +00001198 s = ssl.wrap_socket(socket.socket())
1199 s.connect(('127.0.0.1', server.port))
1200 if test_support.verbose:
1201 sys.stdout.write(
1202 " client: sending %s...\n" % (repr(indata)))
1203 s.write(indata)
1204 outdata = s.read()
1205 if test_support.verbose:
1206 sys.stdout.write(" client: read %s\n" % repr(outdata))
1207 if outdata != indata.lower():
1208 self.fail(
1209 "bad data <<%s>> (%d) received; expected <<%s>> (%d)\n"
1210 % (outdata[:min(len(outdata),20)], len(outdata),
1211 indata[:min(len(indata),20)].lower(), len(indata)))
1212 s.write("over\n")
1213 if test_support.verbose:
1214 sys.stdout.write(" client: closing connection.\n")
1215 s.close()
Bill Janssen934b16d2008-06-28 22:19:33 +00001216
Antoine Pitrou3945c862010-04-28 21:11:01 +00001217 def test_recv_send(self):
1218 """Test recv(), send() and friends."""
Bill Janssen61c001a2008-09-08 16:37:24 +00001219 if test_support.verbose:
1220 sys.stdout.write("\n")
1221
1222 server = ThreadedEchoServer(CERTFILE,
1223 certreqs=ssl.CERT_NONE,
1224 ssl_version=ssl.PROTOCOL_TLSv1,
1225 cacerts=CERTFILE,
1226 chatty=True,
1227 connectionchatty=False)
Antoine Pitrou5b95eb92011-12-21 16:52:40 +01001228 with server:
1229 s = ssl.wrap_socket(socket.socket(),
1230 server_side=False,
1231 certfile=CERTFILE,
1232 ca_certs=CERTFILE,
1233 cert_reqs=ssl.CERT_NONE,
1234 ssl_version=ssl.PROTOCOL_TLSv1)
1235 s.connect((HOST, server.port))
Bill Janssen61c001a2008-09-08 16:37:24 +00001236 # helper methods for standardising recv* method signatures
1237 def _recv_into():
1238 b = bytearray("\0"*100)
1239 count = s.recv_into(b)
1240 return b[:count]
1241
1242 def _recvfrom_into():
1243 b = bytearray("\0"*100)
1244 count, addr = s.recvfrom_into(b)
1245 return b[:count]
1246
1247 # (name, method, whether to expect success, *args)
1248 send_methods = [
1249 ('send', s.send, True, []),
1250 ('sendto', s.sendto, False, ["some.address"]),
1251 ('sendall', s.sendall, True, []),
1252 ]
1253 recv_methods = [
1254 ('recv', s.recv, True, []),
1255 ('recvfrom', s.recvfrom, False, ["some.address"]),
1256 ('recv_into', _recv_into, True, []),
1257 ('recvfrom_into', _recvfrom_into, False, []),
1258 ]
1259 data_prefix = u"PREFIX_"
1260
1261 for meth_name, send_meth, expect_success, args in send_methods:
1262 indata = data_prefix + meth_name
1263 try:
1264 send_meth(indata.encode('ASCII', 'strict'), *args)
1265 outdata = s.read()
1266 outdata = outdata.decode('ASCII', 'strict')
1267 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001268 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001269 "While sending with <<%s>> bad data "
1270 "<<%r>> (%d) received; "
1271 "expected <<%r>> (%d)\n" % (
1272 meth_name, outdata[:20], len(outdata),
1273 indata[:20], len(indata)
1274 )
1275 )
1276 except ValueError as e:
1277 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001278 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001279 "Failed to send with method <<%s>>; "
1280 "expected to succeed.\n" % (meth_name,)
1281 )
1282 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001283 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001284 "Method <<%s>> failed with unexpected "
1285 "exception message: %s\n" % (
1286 meth_name, e
1287 )
1288 )
1289
1290 for meth_name, recv_meth, expect_success, args in recv_methods:
1291 indata = data_prefix + meth_name
1292 try:
1293 s.send(indata.encode('ASCII', 'strict'))
1294 outdata = recv_meth(*args)
1295 outdata = outdata.decode('ASCII', 'strict')
1296 if outdata != indata.lower():
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001297 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001298 "While receiving with <<%s>> bad data "
1299 "<<%r>> (%d) received; "
1300 "expected <<%r>> (%d)\n" % (
1301 meth_name, outdata[:20], len(outdata),
1302 indata[:20], len(indata)
1303 )
1304 )
1305 except ValueError as e:
1306 if expect_success:
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001307 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001308 "Failed to receive with method <<%s>>; "
1309 "expected to succeed.\n" % (meth_name,)
1310 )
1311 if not str(e).startswith(meth_name):
Georg Brandlc7ca56d2010-02-06 23:23:45 +00001312 self.fail(
Bill Janssen61c001a2008-09-08 16:37:24 +00001313 "Method <<%s>> failed with unexpected "
1314 "exception message: %s\n" % (
1315 meth_name, e
1316 )
1317 )
1318 # consume data
1319 s.read()
1320
1321 s.write("over\n".encode("ASCII", "strict"))
1322 s.close()
Bill Janssen61c001a2008-09-08 16:37:24 +00001323
Antoine Pitroufc69af12010-04-24 20:04:58 +00001324 def test_handshake_timeout(self):
1325 # Issue #5103: SSL handshake must respect the socket timeout
1326 server = socket.socket(socket.AF_INET)
1327 host = "127.0.0.1"
1328 port = test_support.bind_port(server)
1329 started = threading.Event()
1330 finish = False
1331
1332 def serve():
1333 server.listen(5)
1334 started.set()
1335 conns = []
1336 while not finish:
1337 r, w, e = select.select([server], [], [], 0.1)
1338 if server in r:
1339 # Let the socket hang around rather than having
1340 # it closed by garbage collection.
1341 conns.append(server.accept()[0])
1342
1343 t = threading.Thread(target=serve)
1344 t.start()
1345 started.wait()
1346
1347 try:
1348 try:
1349 c = socket.socket(socket.AF_INET)
1350 c.settimeout(0.2)
1351 c.connect((host, port))
1352 # Will attempt handshake and time out
1353 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1354 ssl.wrap_socket, c)
1355 finally:
1356 c.close()
1357 try:
1358 c = socket.socket(socket.AF_INET)
1359 c.settimeout(0.2)
1360 c = ssl.wrap_socket(c)
1361 # Will attempt handshake and time out
1362 self.assertRaisesRegexp(ssl.SSLError, "timed out",
1363 c.connect, (host, port))
1364 finally:
1365 c.close()
1366 finally:
1367 finish = True
1368 t.join()
1369 server.close()
1370
Antoine Pitroud76088d2012-01-03 22:46:48 +01001371 def test_default_ciphers(self):
1372 with ThreadedEchoServer(CERTFILE,
1373 ssl_version=ssl.PROTOCOL_SSLv23,
1374 chatty=False) as server:
1375 sock = socket.socket()
1376 try:
1377 # Force a set of weak ciphers on our client socket
1378 try:
1379 s = ssl.wrap_socket(sock,
1380 ssl_version=ssl.PROTOCOL_SSLv23,
1381 ciphers="DES")
1382 except ssl.SSLError:
1383 self.skipTest("no DES cipher available")
1384 with self.assertRaises((OSError, ssl.SSLError)):
1385 s.connect((HOST, server.port))
1386 finally:
1387 sock.close()
1388 self.assertIn("no shared cipher", str(server.conn_errors[0]))
1389
Bill Janssen61c001a2008-09-08 16:37:24 +00001390
Neal Norwitz9eb9b102007-08-27 01:15:33 +00001391def test_main(verbose=False):
Christian Heimes88b174c2013-08-17 00:54:47 +02001392 global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT, NULLBYTECERT
Guido van Rossumba8c5652007-08-27 17:19:42 +00001393 CERTFILE = os.path.join(os.path.dirname(__file__) or os.curdir,
Bill Janssen296a59d2007-09-16 22:06:00 +00001394 "keycert.pem")
1395 SVN_PYTHON_ORG_ROOT_CERT = os.path.join(
1396 os.path.dirname(__file__) or os.curdir,
1397 "https_svn_python_org_root.pem")
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001398 NOKIACERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1399 "nokia.pem")
Christian Heimes88b174c2013-08-17 00:54:47 +02001400 NULLBYTECERT = os.path.join(os.path.dirname(__file__) or os.curdir,
1401 "nullbytecert.pem")
Bill Janssen296a59d2007-09-16 22:06:00 +00001402
1403 if (not os.path.exists(CERTFILE) or
Antoine Pitrouf06eb462011-10-01 19:30:58 +02001404 not os.path.exists(SVN_PYTHON_ORG_ROOT_CERT) or
Christian Heimes88b174c2013-08-17 00:54:47 +02001405 not os.path.exists(NOKIACERT) or
1406 not os.path.exists(NULLBYTECERT)):
Bill Janssen98d19da2007-09-10 21:51:02 +00001407 raise test_support.TestFailed("Can't read certificate files!")
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001408
Antoine Pitroude30f702010-09-14 12:54:08 +00001409 tests = [BasicTests, BasicSocketTests]
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001410
Bill Janssen296a59d2007-09-16 22:06:00 +00001411 if test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001412 tests.append(NetworkedTests)
Bill Janssen296a59d2007-09-16 22:06:00 +00001413
Bill Janssen98d19da2007-09-10 21:51:02 +00001414 if _have_threads:
1415 thread_info = test_support.threading_setup()
Bill Janssen296a59d2007-09-16 22:06:00 +00001416 if thread_info and test_support.is_resource_enabled('network'):
Bill Janssen934b16d2008-06-28 22:19:33 +00001417 tests.append(ThreadedTests)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001418
Antoine Pitrou3945c862010-04-28 21:11:01 +00001419 try:
1420 test_support.run_unittest(*tests)
1421 finally:
1422 if _have_threads:
1423 test_support.threading_cleanup(*thread_info)
Guido van Rossum4f2c3dd2007-08-25 15:08:43 +00001424
1425if __name__ == "__main__":
1426 test_main()