/Lib/test/test_ssl.py
Python | 1992 lines | 1822 code | 88 blank | 82 comment | 96 complexity | 7e074840d6d26eaa127cc5f113275e13 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
1# Test the support for SSL and sockets 2 3import sys 4import unittest 5from test import support 6import socket 7import select 8import time 9import gc 10import os 11import errno 12import pprint 13import tempfile 14import urllib.request 15import traceback 16import asyncore 17import weakref 18import platform 19import functools 20 21ssl = support.import_module("ssl") 22 23PROTOCOLS = [ 24 ssl.PROTOCOL_SSLv3, 25 ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1 26] 27if hasattr(ssl, 'PROTOCOL_SSLv2'): 28 PROTOCOLS.append(ssl.PROTOCOL_SSLv2) 29 30HOST = support.HOST 31 32data_file = lambda name: os.path.join(os.path.dirname(__file__), name) 33 34# The custom key and certificate files used in test_ssl are generated 35# using Lib/test/make_ssl_certs.py. 36# Other certificates are simply fetched from the Internet servers they 37# are meant to authenticate. 38 39CERTFILE = data_file("keycert.pem") 40BYTES_CERTFILE = os.fsencode(CERTFILE) 41ONLYCERT = data_file("ssl_cert.pem") 42ONLYKEY = data_file("ssl_key.pem") 43BYTES_ONLYCERT = os.fsencode(ONLYCERT) 44BYTES_ONLYKEY = os.fsencode(ONLYKEY) 45CERTFILE_PROTECTED = data_file("keycert.passwd.pem") 46ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem") 47KEY_PASSWORD = "somepass" 48CAPATH = data_file("capath") 49BYTES_CAPATH = os.fsencode(CAPATH) 50 51SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem") 52 53EMPTYCERT = data_file("nullcert.pem") 54BADCERT = data_file("badcert.pem") 55WRONGCERT = data_file("XXXnonexisting.pem") 56BADKEY = data_file("badkey.pem") 57NOKIACERT = data_file("nokia.pem") 58 59DHFILE = data_file("dh512.pem") 60BYTES_DHFILE = os.fsencode(DHFILE) 61 62def handle_error(prefix): 63 exc_format = ' '.join(traceback.format_exception(*sys.exc_info())) 64 if support.verbose: 65 sys.stdout.write(prefix + exc_format) 66 67def can_clear_options(): 68 # 0.9.8m or higher 69 return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15) 70 71def no_sslv2_implies_sslv3_hello(): 72 # 0.9.7h or higher 73 return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15) 74 75 76# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2 77def skip_if_broken_ubuntu_ssl(func): 78 if hasattr(ssl, 'PROTOCOL_SSLv2'): 79 @functools.wraps(func) 80 def f(*args, **kwargs): 81 try: 82 ssl.SSLContext(ssl.PROTOCOL_SSLv2) 83 except ssl.SSLError: 84 if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and 85 platform.linux_distribution() == ('debian', 'squeeze/sid', '')): 86 raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour") 87 return func(*args, **kwargs) 88 return f 89 else: 90 return func 91 92 93class BasicSocketTests(unittest.TestCase): 94 95 def test_constants(self): 96 #ssl.PROTOCOL_SSLv2 97 ssl.PROTOCOL_SSLv23 98 ssl.PROTOCOL_SSLv3 99 ssl.PROTOCOL_TLSv1 100 ssl.CERT_NONE 101 ssl.CERT_OPTIONAL 102 ssl.CERT_REQUIRED 103 ssl.OP_CIPHER_SERVER_PREFERENCE 104 ssl.OP_SINGLE_DH_USE 105 if ssl.HAS_ECDH: 106 ssl.OP_SINGLE_ECDH_USE 107 if ssl.OPENSSL_VERSION_INFO >= (1, 0): 108 ssl.OP_NO_COMPRESSION 109 self.assertIn(ssl.HAS_SNI, {True, False}) 110 self.assertIn(ssl.HAS_ECDH, {True, False}) 111 112 def test_random(self): 113 v = ssl.RAND_status() 114 if support.verbose: 115 sys.stdout.write("\n RAND_status is %d (%s)\n" 116 % (v, (v and "sufficient randomness") or 117 "insufficient randomness")) 118 119 data, is_cryptographic = ssl.RAND_pseudo_bytes(16) 120 self.assertEqual(len(data), 16) 121 self.assertEqual(is_cryptographic, v == 1) 122 if v: 123 data = ssl.RAND_bytes(16) 124 self.assertEqual(len(data), 16) 125 else: 126 self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16) 127 128 try: 129 ssl.RAND_egd(1) 130 except TypeError: 131 pass 132 else: 133 print("didn't raise TypeError") 134 ssl.RAND_add("this is a random string", 75.0) 135 136 def test_parse_cert(self): 137 # note that this uses an 'unofficial' function in _ssl.c, 138 # provided solely for this test, to exercise the certificate 139 # parsing code 140 p = ssl._ssl._test_decode_cert(CERTFILE) 141 if support.verbose: 142 sys.stdout.write("\n" + pprint.pformat(p) + "\n") 143 self.assertEqual(p['issuer'], 144 ((('countryName', 'XY'),), 145 (('localityName', 'Castle Anthrax'),), 146 (('organizationName', 'Python Software Foundation'),), 147 (('commonName', 'localhost'),)) 148 ) 149 self.assertEqual(p['notAfter'], 'Oct 5 23:01:56 2020 GMT') 150 self.assertEqual(p['notBefore'], 'Oct 8 23:01:56 2010 GMT') 151 self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E') 152 self.assertEqual(p['subject'], 153 ((('countryName', 'XY'),), 154 (('localityName', 'Castle Anthrax'),), 155 (('organizationName', 'Python Software Foundation'),), 156 (('commonName', 'localhost'),)) 157 ) 158 self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),)) 159 # Issue #13034: the subjectAltName in some certificates 160 # (notably projects.developer.nokia.com:443) wasn't parsed 161 p = ssl._ssl._test_decode_cert(NOKIACERT) 162 if support.verbose: 163 sys.stdout.write("\n" + pprint.pformat(p) + "\n") 164 self.assertEqual(p['subjectAltName'], 165 (('DNS', 'projects.developer.nokia.com'), 166 ('DNS', 'projects.forum.nokia.com')) 167 ) 168 169 def test_DER_to_PEM(self): 170 with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f: 171 pem = f.read() 172 d1 = ssl.PEM_cert_to_DER_cert(pem) 173 p2 = ssl.DER_cert_to_PEM_cert(d1) 174 d2 = ssl.PEM_cert_to_DER_cert(p2) 175 self.assertEqual(d1, d2) 176 if not p2.startswith(ssl.PEM_HEADER + '\n'): 177 self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2) 178 if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'): 179 self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2) 180 181 def test_openssl_version(self): 182 n = ssl.OPENSSL_VERSION_NUMBER 183 t = ssl.OPENSSL_VERSION_INFO 184 s = ssl.OPENSSL_VERSION 185 self.assertIsInstance(n, int) 186 self.assertIsInstance(t, tuple) 187 self.assertIsInstance(s, str) 188 # Some sanity checks follow 189 # >= 0.9 190 self.assertGreaterEqual(n, 0x900000) 191 # < 2.0 192 self.assertLess(n, 0x20000000) 193 major, minor, fix, patch, status = t 194 self.assertGreaterEqual(major, 0) 195 self.assertLess(major, 2) 196 self.assertGreaterEqual(minor, 0) 197 self.assertLess(minor, 256) 198 self.assertGreaterEqual(fix, 0) 199 self.assertLess(fix, 256) 200 self.assertGreaterEqual(patch, 0) 201 self.assertLessEqual(patch, 26) 202 self.assertGreaterEqual(status, 0) 203 self.assertLessEqual(status, 15) 204 # Version string as returned by OpenSSL, the format might change 205 self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)), 206 (s, t)) 207 208 @support.cpython_only 209 def test_refcycle(self): 210 # Issue #7943: an SSL object doesn't create reference cycles with 211 # itself. 212 s = socket.socket(socket.AF_INET) 213 ss = ssl.wrap_socket(s) 214 wr = weakref.ref(ss) 215 del ss 216 self.assertEqual(wr(), None) 217 218 def test_wrapped_unconnected(self): 219 # Methods on an unconnected SSLSocket propagate the original 220 # socket.error raise by the underlying socket object. 221 s = socket.socket(socket.AF_INET) 222 ss = ssl.wrap_socket(s) 223 self.assertRaises(socket.error, ss.recv, 1) 224 self.assertRaises(socket.error, ss.recv_into, bytearray(b'x')) 225 self.assertRaises(socket.error, ss.recvfrom, 1) 226 self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1) 227 self.assertRaises(socket.error, ss.send, b'x') 228 self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0)) 229 230 def test_timeout(self): 231 # Issue #8524: when creating an SSL socket, the timeout of the 232 # original socket should be retained. 233 for timeout in (None, 0.0, 5.0): 234 s = socket.socket(socket.AF_INET) 235 s.settimeout(timeout) 236 ss = ssl.wrap_socket(s) 237 self.assertEqual(timeout, ss.gettimeout()) 238 239 def test_errors(self): 240 sock = socket.socket() 241 self.assertRaisesRegex(ValueError, 242 "certfile must be specified", 243 ssl.wrap_socket, sock, keyfile=CERTFILE) 244 self.assertRaisesRegex(ValueError, 245 "certfile must be specified for server-side operations", 246 ssl.wrap_socket, sock, server_side=True) 247 self.assertRaisesRegex(ValueError, 248 "certfile must be specified for server-side operations", 249 ssl.wrap_socket, sock, server_side=True, certfile="") 250 s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE) 251 self.assertRaisesRegex(ValueError, "can't connect in server-side mode", 252 s.connect, (HOST, 8080)) 253 with self.assertRaises(IOError) as cm: 254 with socket.socket() as sock: 255 ssl.wrap_socket(sock, certfile=WRONGCERT) 256 self.assertEqual(cm.exception.errno, errno.ENOENT) 257 with self.assertRaises(IOError) as cm: 258 with socket.socket() as sock: 259 ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT) 260 self.assertEqual(cm.exception.errno, errno.ENOENT) 261 with self.assertRaises(IOError) as cm: 262 with socket.socket() as sock: 263 ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT) 264 self.assertEqual(cm.exception.errno, errno.ENOENT) 265 266 def test_match_hostname(self): 267 def ok(cert, hostname): 268 ssl.match_hostname(cert, hostname) 269 def fail(cert, hostname): 270 self.assertRaises(ssl.CertificateError, 271 ssl.match_hostname, cert, hostname) 272 273 cert = {'subject': ((('commonName', 'example.com'),),)} 274 ok(cert, 'example.com') 275 ok(cert, 'ExAmple.cOm') 276 fail(cert, 'www.example.com') 277 fail(cert, '.example.com') 278 fail(cert, 'example.org') 279 fail(cert, 'exampleXcom') 280 281 cert = {'subject': ((('commonName', '*.a.com'),),)} 282 ok(cert, 'foo.a.com') 283 fail(cert, 'bar.foo.a.com') 284 fail(cert, 'a.com') 285 fail(cert, 'Xa.com') 286 fail(cert, '.a.com') 287 288 cert = {'subject': ((('commonName', 'a.*.com'),),)} 289 ok(cert, 'a.foo.com') 290 fail(cert, 'a..com') 291 fail(cert, 'a.com') 292 293 cert = {'subject': ((('commonName', 'f*.com'),),)} 294 ok(cert, 'foo.com') 295 ok(cert, 'f.com') 296 fail(cert, 'bar.com') 297 fail(cert, 'foo.a.com') 298 fail(cert, 'bar.foo.com') 299 300 # Slightly fake real-world example 301 cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT', 302 'subject': ((('commonName', 'linuxfrz.org'),),), 303 'subjectAltName': (('DNS', 'linuxfr.org'), 304 ('DNS', 'linuxfr.com'), 305 ('othername', '<unsupported>'))} 306 ok(cert, 'linuxfr.org') 307 ok(cert, 'linuxfr.com') 308 # Not a "DNS" entry 309 fail(cert, '<unsupported>') 310 # When there is a subjectAltName, commonName isn't used 311 fail(cert, 'linuxfrz.org') 312 313 # A pristine real-world example 314 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 315 'subject': ((('countryName', 'US'),), 316 (('stateOrProvinceName', 'California'),), 317 (('localityName', 'Mountain View'),), 318 (('organizationName', 'Google Inc'),), 319 (('commonName', 'mail.google.com'),))} 320 ok(cert, 'mail.google.com') 321 fail(cert, 'gmail.com') 322 # Only commonName is considered 323 fail(cert, 'California') 324 325 # Neither commonName nor subjectAltName 326 cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT', 327 'subject': ((('countryName', 'US'),), 328 (('stateOrProvinceName', 'California'),), 329 (('localityName', 'Mountain View'),), 330 (('organizationName', 'Google Inc'),))} 331 fail(cert, 'mail.google.com') 332 333 # No DNS entry in subjectAltName but a commonName 334 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 335 'subject': ((('countryName', 'US'),), 336 (('stateOrProvinceName', 'California'),), 337 (('localityName', 'Mountain View'),), 338 (('commonName', 'mail.google.com'),)), 339 'subjectAltName': (('othername', 'blabla'), )} 340 ok(cert, 'mail.google.com') 341 342 # No DNS entry subjectAltName and no commonName 343 cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT', 344 'subject': ((('countryName', 'US'),), 345 (('stateOrProvinceName', 'California'),), 346 (('localityName', 'Mountain View'),), 347 (('organizationName', 'Google Inc'),)), 348 'subjectAltName': (('othername', 'blabla'),)} 349 fail(cert, 'google.com') 350 351 # Empty cert / no cert 352 self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com') 353 self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com') 354 355 def test_server_side(self): 356 # server_hostname doesn't work for server sockets 357 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 358 with socket.socket() as sock: 359 self.assertRaises(ValueError, ctx.wrap_socket, sock, True, 360 server_hostname="some.hostname") 361 362 def test_unknown_channel_binding(self): 363 # should raise ValueError for unknown type 364 s = socket.socket(socket.AF_INET) 365 ss = ssl.wrap_socket(s) 366 with self.assertRaises(ValueError): 367 ss.get_channel_binding("unknown-type") 368 369 @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES, 370 "'tls-unique' channel binding not available") 371 def test_tls_unique_channel_binding(self): 372 # unconnected should return None for known type 373 s = socket.socket(socket.AF_INET) 374 ss = ssl.wrap_socket(s) 375 self.assertIsNone(ss.get_channel_binding("tls-unique")) 376 # the same for server-side 377 s = socket.socket(socket.AF_INET) 378 ss = ssl.wrap_socket(s, server_side=True, certfile=CERTFILE) 379 self.assertIsNone(ss.get_channel_binding("tls-unique")) 380 381class ContextTests(unittest.TestCase): 382 383 @skip_if_broken_ubuntu_ssl 384 def test_constructor(self): 385 if hasattr(ssl, 'PROTOCOL_SSLv2'): 386 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2) 387 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 388 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3) 389 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 390 self.assertRaises(TypeError, ssl.SSLContext) 391 self.assertRaises(ValueError, ssl.SSLContext, -1) 392 self.assertRaises(ValueError, ssl.SSLContext, 42) 393 394 @skip_if_broken_ubuntu_ssl 395 def test_protocol(self): 396 for proto in PROTOCOLS: 397 ctx = ssl.SSLContext(proto) 398 self.assertEqual(ctx.protocol, proto) 399 400 def test_ciphers(self): 401 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 402 ctx.set_ciphers("ALL") 403 ctx.set_ciphers("DEFAULT") 404 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): 405 ctx.set_ciphers("^$:,;?*'dorothyx") 406 407 @skip_if_broken_ubuntu_ssl 408 def test_options(self): 409 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 410 # OP_ALL is the default value 411 self.assertEqual(ssl.OP_ALL, ctx.options) 412 ctx.options |= ssl.OP_NO_SSLv2 413 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2, 414 ctx.options) 415 ctx.options |= ssl.OP_NO_SSLv3 416 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3, 417 ctx.options) 418 if can_clear_options(): 419 ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1 420 self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3, 421 ctx.options) 422 ctx.options = 0 423 self.assertEqual(0, ctx.options) 424 else: 425 with self.assertRaises(ValueError): 426 ctx.options = 0 427 428 def test_verify(self): 429 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 430 # Default value 431 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) 432 ctx.verify_mode = ssl.CERT_OPTIONAL 433 self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL) 434 ctx.verify_mode = ssl.CERT_REQUIRED 435 self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) 436 ctx.verify_mode = ssl.CERT_NONE 437 self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) 438 with self.assertRaises(TypeError): 439 ctx.verify_mode = None 440 with self.assertRaises(ValueError): 441 ctx.verify_mode = 42 442 443 def test_load_cert_chain(self): 444 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 445 # Combined key and cert in a single file 446 ctx.load_cert_chain(CERTFILE) 447 ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE) 448 self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE) 449 with self.assertRaises(IOError) as cm: 450 ctx.load_cert_chain(WRONGCERT) 451 self.assertEqual(cm.exception.errno, errno.ENOENT) 452 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 453 ctx.load_cert_chain(BADCERT) 454 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 455 ctx.load_cert_chain(EMPTYCERT) 456 # Separate key and cert 457 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 458 ctx.load_cert_chain(ONLYCERT, ONLYKEY) 459 ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY) 460 ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY) 461 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 462 ctx.load_cert_chain(ONLYCERT) 463 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 464 ctx.load_cert_chain(ONLYKEY) 465 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 466 ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT) 467 # Mismatching key and cert 468 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 469 with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"): 470 ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY) 471 # Password protected key and cert 472 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD) 473 ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode()) 474 ctx.load_cert_chain(CERTFILE_PROTECTED, 475 password=bytearray(KEY_PASSWORD.encode())) 476 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD) 477 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode()) 478 ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, 479 bytearray(KEY_PASSWORD.encode())) 480 with self.assertRaisesRegex(TypeError, "should be a string"): 481 ctx.load_cert_chain(CERTFILE_PROTECTED, password=True) 482 with self.assertRaises(ssl.SSLError): 483 ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass") 484 with self.assertRaisesRegex(ValueError, "cannot be longer"): 485 # openssl has a fixed limit on the password buffer. 486 # PEM_BUFSIZE is generally set to 1kb. 487 # Return a string larger than this. 488 ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400) 489 # Password callback 490 def getpass_unicode(): 491 return KEY_PASSWORD 492 def getpass_bytes(): 493 return KEY_PASSWORD.encode() 494 def getpass_bytearray(): 495 return bytearray(KEY_PASSWORD.encode()) 496 def getpass_badpass(): 497 return "badpass" 498 def getpass_huge(): 499 return b'a' * (1024 * 1024) 500 def getpass_bad_type(): 501 return 9 502 def getpass_exception(): 503 raise Exception('getpass error') 504 class GetPassCallable: 505 def __call__(self): 506 return KEY_PASSWORD 507 def getpass(self): 508 return KEY_PASSWORD 509 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode) 510 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes) 511 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray) 512 ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable()) 513 ctx.load_cert_chain(CERTFILE_PROTECTED, 514 password=GetPassCallable().getpass) 515 with self.assertRaises(ssl.SSLError): 516 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass) 517 with self.assertRaisesRegex(ValueError, "cannot be longer"): 518 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge) 519 with self.assertRaisesRegex(TypeError, "must return a string"): 520 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type) 521 with self.assertRaisesRegex(Exception, "getpass error"): 522 ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception) 523 # Make sure the password function isn't called if it isn't needed 524 ctx.load_cert_chain(CERTFILE, password=getpass_exception) 525 526 def test_load_verify_locations(self): 527 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 528 ctx.load_verify_locations(CERTFILE) 529 ctx.load_verify_locations(cafile=CERTFILE, capath=None) 530 ctx.load_verify_locations(BYTES_CERTFILE) 531 ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None) 532 self.assertRaises(TypeError, ctx.load_verify_locations) 533 self.assertRaises(TypeError, ctx.load_verify_locations, None, None) 534 with self.assertRaises(IOError) as cm: 535 ctx.load_verify_locations(WRONGCERT) 536 self.assertEqual(cm.exception.errno, errno.ENOENT) 537 with self.assertRaisesRegex(ssl.SSLError, "PEM lib"): 538 ctx.load_verify_locations(BADCERT) 539 ctx.load_verify_locations(CERTFILE, CAPATH) 540 ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH) 541 542 # Issue #10989: crash if the second argument type is invalid 543 self.assertRaises(TypeError, ctx.load_verify_locations, None, True) 544 545 def test_load_dh_params(self): 546 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 547 ctx.load_dh_params(DHFILE) 548 if os.name != 'nt': 549 ctx.load_dh_params(BYTES_DHFILE) 550 self.assertRaises(TypeError, ctx.load_dh_params) 551 self.assertRaises(TypeError, ctx.load_dh_params, None) 552 with self.assertRaises(FileNotFoundError) as cm: 553 ctx.load_dh_params(WRONGCERT) 554 self.assertEqual(cm.exception.errno, errno.ENOENT) 555 with self.assertRaises(ssl.SSLError) as cm: 556 ctx.load_dh_params(CERTFILE) 557 558 @skip_if_broken_ubuntu_ssl 559 def test_session_stats(self): 560 for proto in PROTOCOLS: 561 ctx = ssl.SSLContext(proto) 562 self.assertEqual(ctx.session_stats(), { 563 'number': 0, 564 'connect': 0, 565 'connect_good': 0, 566 'connect_renegotiate': 0, 567 'accept': 0, 568 'accept_good': 0, 569 'accept_renegotiate': 0, 570 'hits': 0, 571 'misses': 0, 572 'timeouts': 0, 573 'cache_full': 0, 574 }) 575 576 def test_set_default_verify_paths(self): 577 # There's not much we can do to test that it acts as expected, 578 # so just check it doesn't crash or raise an exception. 579 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 580 ctx.set_default_verify_paths() 581 582 @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build") 583 def test_set_ecdh_curve(self): 584 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 585 ctx.set_ecdh_curve("prime256v1") 586 ctx.set_ecdh_curve(b"prime256v1") 587 self.assertRaises(TypeError, ctx.set_ecdh_curve) 588 self.assertRaises(TypeError, ctx.set_ecdh_curve, None) 589 self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo") 590 self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo") 591 592 593class SSLErrorTests(unittest.TestCase): 594 595 def test_str(self): 596 # The str() of a SSLError doesn't include the errno 597 e = ssl.SSLError(1, "foo") 598 self.assertEqual(str(e), "foo") 599 self.assertEqual(e.errno, 1) 600 # Same for a subclass 601 e = ssl.SSLZeroReturnError(1, "foo") 602 self.assertEqual(str(e), "foo") 603 self.assertEqual(e.errno, 1) 604 605 def test_lib_reason(self): 606 # Test the library and reason attributes 607 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 608 with self.assertRaises(ssl.SSLError) as cm: 609 ctx.load_dh_params(CERTFILE) 610 self.assertEqual(cm.exception.library, 'PEM') 611 self.assertEqual(cm.exception.reason, 'NO_START_LINE') 612 s = str(cm.exception) 613 self.assertTrue(s.startswith("[PEM: NO_START_LINE] no start line"), s) 614 615 def test_subclass(self): 616 # Check that the appropriate SSLError subclass is raised 617 # (this only tests one of them) 618 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 619 with socket.socket() as s: 620 s.bind(("127.0.0.1", 0)) 621 s.listen(5) 622 with socket.socket() as c: 623 c.connect(s.getsockname()) 624 c.setblocking(False) 625 c = ctx.wrap_socket(c, False, do_handshake_on_connect=False) 626 with self.assertRaises(ssl.SSLWantReadError) as cm: 627 c.do_handshake() 628 s = str(cm.exception) 629 self.assertTrue(s.startswith("The operation did not complete (read)"), s) 630 # For compatibility 631 self.assertEqual(cm.exception.errno, ssl.SSL_ERROR_WANT_READ) 632 633 634class NetworkedTests(unittest.TestCase): 635 636 def test_connect(self): 637 with support.transient_internet("svn.python.org"): 638 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 639 cert_reqs=ssl.CERT_NONE) 640 try: 641 s.connect(("svn.python.org", 443)) 642 self.assertEqual({}, s.getpeercert()) 643 finally: 644 s.close() 645 646 # this should fail because we have no verification certs 647 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 648 cert_reqs=ssl.CERT_REQUIRED) 649 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", 650 s.connect, ("svn.python.org", 443)) 651 s.close() 652 653 # this should succeed because we specify the root cert 654 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 655 cert_reqs=ssl.CERT_REQUIRED, 656 ca_certs=SVN_PYTHON_ORG_ROOT_CERT) 657 try: 658 s.connect(("svn.python.org", 443)) 659 self.assertTrue(s.getpeercert()) 660 finally: 661 s.close() 662 663 def test_connect_ex(self): 664 # Issue #11326: check connect_ex() implementation 665 with support.transient_internet("svn.python.org"): 666 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 667 cert_reqs=ssl.CERT_REQUIRED, 668 ca_certs=SVN_PYTHON_ORG_ROOT_CERT) 669 try: 670 self.assertEqual(0, s.connect_ex(("svn.python.org", 443))) 671 self.assertTrue(s.getpeercert()) 672 finally: 673 s.close() 674 675 def test_non_blocking_connect_ex(self): 676 # Issue #11326: non-blocking connect_ex() should allow handshake 677 # to proceed after the socket gets ready. 678 with support.transient_internet("svn.python.org"): 679 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 680 cert_reqs=ssl.CERT_REQUIRED, 681 ca_certs=SVN_PYTHON_ORG_ROOT_CERT, 682 do_handshake_on_connect=False) 683 try: 684 s.setblocking(False) 685 rc = s.connect_ex(('svn.python.org', 443)) 686 # EWOULDBLOCK under Windows, EINPROGRESS elsewhere 687 self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK)) 688 # Wait for connect to finish 689 select.select([], [s], [], 5.0) 690 # Non-blocking handshake 691 while True: 692 try: 693 s.do_handshake() 694 break 695 except ssl.SSLWantReadError: 696 select.select([s], [], [], 5.0) 697 except ssl.SSLWantWriteError: 698 select.select([], [s], [], 5.0) 699 # SSL established 700 self.assertTrue(s.getpeercert()) 701 finally: 702 s.close() 703 704 def test_timeout_connect_ex(self): 705 # Issue #12065: on a timeout, connect_ex() should return the original 706 # errno (mimicking the behaviour of non-SSL sockets). 707 with support.transient_internet("svn.python.org"): 708 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 709 cert_reqs=ssl.CERT_REQUIRED, 710 ca_certs=SVN_PYTHON_ORG_ROOT_CERT, 711 do_handshake_on_connect=False) 712 try: 713 s.settimeout(0.0000001) 714 rc = s.connect_ex(('svn.python.org', 443)) 715 if rc == 0: 716 self.skipTest("svn.python.org responded too quickly") 717 self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK)) 718 finally: 719 s.close() 720 721 def test_connect_with_context(self): 722 with support.transient_internet("svn.python.org"): 723 # Same as test_connect, but with a separately created context 724 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 725 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 726 s.connect(("svn.python.org", 443)) 727 try: 728 self.assertEqual({}, s.getpeercert()) 729 finally: 730 s.close() 731 # Same with a server hostname 732 s = ctx.wrap_socket(socket.socket(socket.AF_INET), 733 server_hostname="svn.python.org") 734 if ssl.HAS_SNI: 735 s.connect(("svn.python.org", 443)) 736 s.close() 737 else: 738 self.assertRaises(ValueError, s.connect, ("svn.python.org", 443)) 739 # This should fail because we have no verification certs 740 ctx.verify_mode = ssl.CERT_REQUIRED 741 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 742 self.assertRaisesRegex(ssl.SSLError, "certificate verify failed", 743 s.connect, ("svn.python.org", 443)) 744 s.close() 745 # This should succeed because we specify the root cert 746 ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT) 747 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 748 s.connect(("svn.python.org", 443)) 749 try: 750 cert = s.getpeercert() 751 self.assertTrue(cert) 752 finally: 753 s.close() 754 755 def test_connect_capath(self): 756 # Verify server certificates using the `capath` argument 757 # NOTE: the subject hashing algorithm has been changed between 758 # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must 759 # contain both versions of each certificate (same content, different 760 # filename) for this test to be portable across OpenSSL releases. 761 with support.transient_internet("svn.python.org"): 762 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 763 ctx.verify_mode = ssl.CERT_REQUIRED 764 ctx.load_verify_locations(capath=CAPATH) 765 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 766 s.connect(("svn.python.org", 443)) 767 try: 768 cert = s.getpeercert() 769 self.assertTrue(cert) 770 finally: 771 s.close() 772 # Same with a bytes `capath` argument 773 ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) 774 ctx.verify_mode = ssl.CERT_REQUIRED 775 ctx.load_verify_locations(capath=BYTES_CAPATH) 776 s = ctx.wrap_socket(socket.socket(socket.AF_INET)) 777 s.connect(("svn.python.org", 443)) 778 try: 779 cert = s.getpeercert() 780 self.assertTrue(cert) 781 finally: 782 s.close() 783 784 @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows") 785 def test_makefile_close(self): 786 # Issue #5238: creating a file-like object with makefile() shouldn't 787 # delay closing the underlying "real socket" (here tested with its 788 # file descriptor, hence skipping the test under Windows). 789 with support.transient_internet("svn.python.org"): 790 ss = ssl.wrap_socket(socket.socket(socket.AF_INET)) 791 ss.connect(("svn.python.org", 443)) 792 fd = ss.fileno() 793 f = ss.makefile() 794 f.close() 795 # The fd is still open 796 os.read(fd, 0) 797 # Closing the SSL socket should close the fd too 798 ss.close() 799 gc.collect() 800 with self.assertRaises(OSError) as e: 801 os.read(fd, 0) 802 self.assertEqual(e.exception.errno, errno.EBADF) 803 804 def test_non_blocking_handshake(self): 805 with support.transient_internet("svn.python.org"): 806 s = socket.socket(socket.AF_INET) 807 s.connect(("svn.python.org", 443)) 808 s.setblocking(False) 809 s = ssl.wrap_socket(s, 810 cert_reqs=ssl.CERT_NONE, 811 do_handshake_on_connect=False) 812 count = 0 813 while True: 814 try: 815 count += 1 816 s.do_handshake() 817 break 818 except ssl.SSLWantReadError: 819 select.select([s], [], []) 820 except ssl.SSLWantWriteError: 821 select.select([], [s], []) 822 s.close() 823 if support.verbose: 824 sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count) 825 826 def test_get_server_certificate(self): 827 def _test_get_server_certificate(host, port, cert=None): 828 with support.transient_internet(host): 829 pem = ssl.get_server_certificate((host, port)) 830 if not pem: 831 self.fail("No server certificate on %s:%s!" % (host, port)) 832 833 try: 834 pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE) 835 except ssl.SSLError as x: 836 #should fail 837 if support.verbose: 838 sys.stdout.write("%s\n" % x) 839 else: 840 self.fail("Got server certificate %s for %s:%s!" % (pem, host, port)) 841 842 pem = ssl.get_server_certificate((host, port), ca_certs=cert) 843 if not pem: 844 self.fail("No server certificate on %s:%s!" % (host, port)) 845 if support.verbose: 846 sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem)) 847 848 _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT) 849 if support.IPV6_ENABLED: 850 _test_get_server_certificate('ipv6.google.com', 443) 851 852 def test_ciphers(self): 853 remote = ("svn.python.org", 443) 854 with support.transient_internet(remote[0]): 855 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 856 cert_reqs=ssl.CERT_NONE, ciphers="ALL") 857 s.connect(remote) 858 s = ssl.wrap_socket(socket.socket(socket.AF_INET), 859 cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT") 860 s.connect(remote) 861 # Error checking can happen at instantiation or when connecting 862 with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"): 863 with socket.socket(socket.AF_INET) as sock: 864 s = ssl.wrap_socket(sock, 865 cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx") 866 s.connect(remote) 867 868 def test_algorithms(self): 869 # Issue #8484: all algorithms should be available when verifying a 870 # certificate. 871 # SHA256 was added in OpenSSL 0.9.8 872 if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15): 873 self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION) 874 # sha256.tbs-internet.com needs SNI to use the correct certificate 875 if not ssl.HAS_SNI: 876 self.skipTest("SNI needed for this test") 877 # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host) 878 remote = ("sha256.tbs-internet.com", 443) 879 sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem") 880 with support.transient_internet("sha256.tbs-internet.com"): 881 ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) 882 ctx.verify_mode = ssl.CERT_REQUIRED 883 ctx.load_verify_locations(sha256_cert) 884 s = ctx.wrap_socket(socket.socket(socket.AF_INET), 885 server_hostname="sha256.tbs-internet.com") 886 try: 887 s.connect(remote) 888 if support.verbose: 889 sys.stdout.write("\nCipher with %r is %r\n" % 890 (remote, s.cipher())) 891 sys.stdout.write("Certificate is:\n%s\n" % 892 pprint.pformat(s.getpeercert())) 893 finally: 894 s.close() 895 896 897try: 898 import threading 899except ImportError: 900 _have_threads = False 901else: 902 _have_threads = True 903 904 from test.ssl_servers import make_https_server 905 906 class ThreadedEchoServer(threading.Thread): 907 908 class ConnectionHandler(threading.Thread): 909 910 """A mildly complicated class, because we want it to work both 911 with and without the SSL wrapper around the socket connection, so 912 that we can test the STARTTLS functionality.""" 913 914 def __init__(self, server, connsock, addr): 915 self.server = server 916 self.running = False 917 self.sock = connsock 918 self.addr = addr 919 self.sock.setblocking(1) 920 self.sslconn = None 921 threading.Thread.__init__(self) 922 self.daemon = True 923 924 def wrap_conn(self): 925 try: 926 self.sslconn = self.server.context.wrap_socket( 927 self.sock, server_side=True) 928 self.server.selected_protocols.append(self.sslconn.selected_npn_protocol()) 929 except ssl.SSLError as e: 930 # XXX Various errors can have happened here, for example 931 # a mismatching protocol version, an invalid certificate, 932 # or a low-level bug. This should be made more discriminating. 933 self.server.conn_errors.append(e) 934 if self.server.chatty: 935 handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n") 936 self.running = False 937 self.server.stop() 938 self.close() 939 return False 940 else: 941 if self.server.context.verify_mode == ssl.CERT_REQUIRED: 942 cert = self.sslconn.getpeercert() 943 if support.verbose and self.server.chatty: 944 sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n") 945 cert_binary = self.sslconn.getpeercert(True) 946 if support.verbose and self.server.chatty: 947 sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n") 948 cipher = self.sslconn.cipher() 949 if support.verbose and self.server.chatty: 950 sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n") 951 sys.stdout.write(" server: selected protocol is now " 952 + str(self.sslconn.selected_npn_protocol()) + "\n") 953 return True 954 955 def read(self): 956 if self.sslconn: 957 return self.sslconn.read() 958 else: 959 return self.sock.recv(1024) 960 961 def write(self, bytes): 962 if self.sslconn: 963 return self.sslconn.write(bytes) 964 else: 965 return self.sock.send(bytes) 966 967 def close(self): 968 if self.sslconn: 969 self.sslconn.close() 970 else: 971 self.sock.close() 972 973 def run(self): 974 self.running = True 975 if not self.server.starttls_server: 976 if not self.wrap_conn(): 977 return 978 while self.running: 979 try: 980 msg = self.read() 981 stripped = msg.strip() 982 if not stripped: 983 # eof, so quit this handler 984 self.running = False 985 self.close() 986 elif stripped == b'over': 987 if support.verbose and self.server.connectionchatty: 988 sys.stdout.write(" server: client closed connection\n") 989 self.close() 990 return 991 elif (self.server.starttls_server and 992 stripped == b'STARTTLS'): 993 if support.verbose and self.server.connectionchatty: 994 sys.stdout.write(" server: read STARTTLS from client, sending OK...\n") 995 self.write(b"OK\n") 996 if not self.wrap_conn(): 997 return 998 elif (self.server.starttls_server and self.sslconn 999 and stripped == b'ENDTLS'): 1000 if support.verbose and self.server.connectionchatty: 1001 sys.stdout.write(" server: read ENDTLS from client, sending OK...\n") 1002 self.write(b"OK\n") 1003 self.sock = self.sslconn.unwrap() 1004 self.sslconn = None 1005 if support.verbose and self.server.connectionchatty: 1006 sys.stdout.write(" server: connection is now unencrypted...\n") 1007 elif stripped == b'CB tls-unique': 1008 if support.verbose and self.server.connectionchatty: 1009 sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n") 1010 data = self.sslconn.get_channel_binding("tls-unique") 1011 self.write(repr(data).encode("us-ascii") + b"\n") 1012 else: 1013 if (support.verbose and 1014 self.server.connectionchatty): 1015 ctype = (self.sslconn and "encrypted") or "unencrypted" 1016 sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n" 1017 % (msg, ctype, msg.lower(), ctype)) 1018 self.write(msg.lower()) 1019 except socket.error: 1020 if self.server.chatty: 1021 handle_error("Test server failure:\n") 1022 self.close() 1023 self.running = False 1024 # normally, we'd just stop here, but for the test 1025 # harness, we want to stop the server 1026 self.server.stop() 1027 1028 def __init__(self, certificate=None, ssl_version=None, 1029 certreqs=None, cacerts=None, 1030 chatty=True, connectionchatty=False, starttls_server=False, 1031 npn_protocols=None, ciphers=None, context=None): 1032 if context: 1033 self.context = context 1034 else: 1035 self.context = ssl.SSLContext(ssl_version 1036 if ssl_version is not None 1037 else ssl.PROTOCOL_TLSv1) 1038 self.context.verify_mode = (certreqs if certreqs is not None 1039 else ssl.CERT_NONE) 1040 if cacerts: 1041 self.context.load_verify_locations(cacerts) 1042 if certificate: 1043 self.context.load_cert_chain(certificate) 1044 if npn_protocols: 1045 self.context.set_npn_protocols(npn_protocols) 1046 if ciphers: 1047 self.context.set_ciphers(ciphers) 1048 self.chatty = chatty 1049 self.connectionchatty = connectionchatty 1050 self.starttls_server = starttls_server 1051 self.sock = socket.socket() 1052 self.port = support.bind_port(self.sock) 1053 self.flag = None 1054 self.active = False 1055 self.selected_protocols = [] 1056 self.conn_errors = [] 1057 threading.Thread.__init__(self) 1058 self.daemon = True 1059 1060 def __enter__(self): 1061 self.start(threading.Event()) 1062 self.flag.wait() 1063 return self 1064 1065 def __exit__(self, *args): 1066 self.stop() 1067 self.join() 1068 1069 def start(self, flag=None): 1070 self.flag = flag 1071 threading.Thread.start(self) 1072 1073 def run(self): 1074 self.sock.settimeout(0.05) 1075 self.sock.listen(5) 1076 self.active = True 1077 if self.flag: 1078 # signal an event 1079 self.flag.set() 1080 while self.active: 1081 try: 1082 newconn, connaddr = self.sock.accept() 1083 if support.verbose and self.chatty: 1084 sys.stdout.write(' server: new connection from ' 1085 + repr(connaddr) + '\n') 1086 handler = self.ConnectionHandler(self, newconn, connaddr) 1087 handler.start() 1088 handler.join() 1089 except socket.timeout: 1090 pass 1091 except KeyboardInterrupt: 1092 self.stop() 1093 self.sock.close() 1094 1095 def stop(self): 1096 self.active = False 1097 1098 class AsyncoreEchoServer(threading.Thread): 1099 1100 # this one's based on asyncore.dispatcher 1101 1102 class EchoServer (asyncore.dispatcher): 1103 1104 class ConnectionHandler (asyncore.dispatcher_with_send): 1105 1106 def __init__(self, conn, certfile): 1107 self.socket = ssl.wrap_socket(conn, server_side=True, 1108 certfile=certfile, 1109 do_handshake_on_connect=False) 1110 asyncore.dispatcher_with_send.__init__(self, self.socket) 1111 self._ssl_accepting = True 1112 self._do_ssl_handshake() 1113 1114 def readable(self): 1115 if isinstance(self.socket, ssl.SSLSocket): 1116 while self.socket.pending() > 0: 1117 self.handle_read_event() 1118 return True 1119 1120 def _do_ssl_handshake(self): 1121 try: 1122 self.socket.do_handshake() 1123 except (ssl.SSLWantReadError, ssl.SSLWantWriteError): 1124 return 1125 except ssl.SSLEOFError: 1126 return self.handle_close() 1127 except ssl.SSLError: 1128 raise 1129 except socket.error as err: 1130 if err.args[0] == errno.ECONNABORTED: 1131 return self.handle_close() 1132 else: 1133 self._ssl_accepting = False 1134 1135 def handle_read(self): 1136 if self._ssl_accepting: 1137 self._do_ssl_handshake() 1138 else: 1139 data = self.recv(1024) 1140 if support.verbose: 1141 sys.stdout.write(" server: read %s from client\n" % repr(data)) 1142 if not data: 1143 self.close() 1144 else: 1145 self.send(data.lower()) 1146 1147 def handle_close(self): 1148 self.close() 1149 if support.verbose: 1150 sys.stdout.write(" server: closed connection %s\n" % self.socket) 1151 1152 def handle_error(self): 1153 raise 1154 1155 def __init__(self, ce…
Large files files are truncated, but you can click here to view the full file