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