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