PageRenderTime 82ms CodeModel.GetById 3ms app.highlight 68ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_ssl.py

https://bitbucket.org/pombredanne/cpython
Python | 2035 lines | 1848 code | 95 blank | 92 comment | 101 complexity | 466e3a8b8c1b233f8a75e2fdbb7b06b7 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        # OSError raise by the underlying socket object.
 217        s = socket.socket(socket.AF_INET)
 218        ss = ssl.wrap_socket(s)
 219        self.assertRaises(OSError, ss.recv, 1)
 220        self.assertRaises(OSError, ss.recv_into, bytearray(b'x'))
 221        self.assertRaises(OSError, ss.recvfrom, 1)
 222        self.assertRaises(OSError, ss.recvfrom_into, bytearray(b'x'), 1)
 223        self.assertRaises(OSError, ss.send, b'x')
 224        self.assertRaises(OSError, 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(OSError) 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(OSError) 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(OSError) 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(OSError) 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(OSError) 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_ex_error(self):
 718        with support.transient_internet("svn.python.org"):
 719            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 720                                cert_reqs=ssl.CERT_REQUIRED,
 721                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
 722            try:
 723                self.assertEqual(errno.ECONNREFUSED,
 724                                 s.connect_ex(("svn.python.org", 444)))
 725            finally:
 726                s.close()
 727
 728    def test_connect_with_context(self):
 729        with support.transient_internet("svn.python.org"):
 730            # Same as test_connect, but with a separately created context
 731            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 732            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 733            s.connect(("svn.python.org", 443))
 734            try:
 735                self.assertEqual({}, s.getpeercert())
 736            finally:
 737                s.close()
 738            # Same with a server hostname
 739            s = ctx.wrap_socket(socket.socket(socket.AF_INET),
 740                                server_hostname="svn.python.org")
 741            if ssl.HAS_SNI:
 742                s.connect(("svn.python.org", 443))
 743                s.close()
 744            else:
 745                self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
 746            # This should fail because we have no verification certs
 747            ctx.verify_mode = ssl.CERT_REQUIRED
 748            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 749            self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
 750                                    s.connect, ("svn.python.org", 443))
 751            s.close()
 752            # This should succeed because we specify the root cert
 753            ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
 754            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 755            s.connect(("svn.python.org", 443))
 756            try:
 757                cert = s.getpeercert()
 758                self.assertTrue(cert)
 759            finally:
 760                s.close()
 761
 762    def test_connect_capath(self):
 763        # Verify server certificates using the `capath` argument
 764        # NOTE: the subject hashing algorithm has been changed between
 765        # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
 766        # contain both versions of each certificate (same content, different
 767        # filename) for this test to be portable across OpenSSL releases.
 768        with support.transient_internet("svn.python.org"):
 769            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 770            ctx.verify_mode = ssl.CERT_REQUIRED
 771            ctx.load_verify_locations(capath=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            # Same with a bytes `capath` argument
 780            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 781            ctx.verify_mode = ssl.CERT_REQUIRED
 782            ctx.load_verify_locations(capath=BYTES_CAPATH)
 783            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 784            s.connect(("svn.python.org", 443))
 785            try:
 786                cert = s.getpeercert()
 787                self.assertTrue(cert)
 788            finally:
 789                s.close()
 790
 791    @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
 792    def test_makefile_close(self):
 793        # Issue #5238: creating a file-like object with makefile() shouldn't
 794        # delay closing the underlying "real socket" (here tested with its
 795        # file descriptor, hence skipping the test under Windows).
 796        with support.transient_internet("svn.python.org"):
 797            ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
 798            ss.connect(("svn.python.org", 443))
 799            fd = ss.fileno()
 800            f = ss.makefile()
 801            f.close()
 802            # The fd is still open
 803            os.read(fd, 0)
 804            # Closing the SSL socket should close the fd too
 805            ss.close()
 806            gc.collect()
 807            with self.assertRaises(OSError) as e:
 808                os.read(fd, 0)
 809            self.assertEqual(e.exception.errno, errno.EBADF)
 810
 811    def test_non_blocking_handshake(self):
 812        with support.transient_internet("svn.python.org"):
 813            s = socket.socket(socket.AF_INET)
 814            s.connect(("svn.python.org", 443))
 815            s.setblocking(False)
 816            s = ssl.wrap_socket(s,
 817                                cert_reqs=ssl.CERT_NONE,
 818                                do_handshake_on_connect=False)
 819            count = 0
 820            while True:
 821                try:
 822                    count += 1
 823                    s.do_handshake()
 824                    break
 825                except ssl.SSLWantReadError:
 826                    select.select([s], [], [])
 827                except ssl.SSLWantWriteError:
 828                    select.select([], [s], [])
 829            s.close()
 830            if support.verbose:
 831                sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
 832
 833    def test_get_server_certificate(self):
 834        def _test_get_server_certificate(host, port, cert=None):
 835            with support.transient_internet(host):
 836                pem = ssl.get_server_certificate((host, port))
 837                if not pem:
 838                    self.fail("No server certificate on %s:%s!" % (host, port))
 839
 840                try:
 841                    pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
 842                except ssl.SSLError as x:
 843                    #should fail
 844                    if support.verbose:
 845                        sys.stdout.write("%s\n" % x)
 846                else:
 847                    self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
 848
 849                pem = ssl.get_server_certificate((host, port), ca_certs=cert)
 850                if not pem:
 851                    self.fail("No server certificate on %s:%s!" % (host, port))
 852                if support.verbose:
 853                    sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
 854
 855        _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
 856        if support.IPV6_ENABLED:
 857            _test_get_server_certificate('ipv6.google.com', 443)
 858
 859    def test_ciphers(self):
 860        remote = ("svn.python.org", 443)
 861        with support.transient_internet(remote[0]):
 862            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 863                                cert_reqs=ssl.CERT_NONE, ciphers="ALL")
 864            s.connect(remote)
 865            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 866                                cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
 867            s.connect(remote)
 868            # Error checking can happen at instantiation or when connecting
 869            with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
 870                with socket.socket(socket.AF_INET) as sock:
 871                    s = ssl.wrap_socket(sock,
 872                                        cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
 873                    s.connect(remote)
 874
 875    def test_algorithms(self):
 876        # Issue #8484: all algorithms should be available when verifying a
 877        # certificate.
 878        # SHA256 was added in OpenSSL 0.9.8
 879        if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
 880            self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
 881        # sha256.tbs-internet.com needs SNI to use the correct certificate
 882        if not ssl.HAS_SNI:
 883            self.skipTest("SNI needed for this test")
 884        # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
 885        remote = ("sha256.tbs-internet.com", 443)
 886        sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
 887        with support.transient_internet("sha256.tbs-internet.com"):
 888            ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 889            ctx.verify_mode = ssl.CERT_REQUIRED
 890            ctx.load_verify_locations(sha256_cert)
 891            s = ctx.wrap_socket(socket.socket(socket.AF_INET),
 892                                server_hostname="sha256.tbs-internet.com")
 893            try:
 894                s.connect(remote)
 895                if support.verbose:
 896                    sys.stdout.write("\nCipher with %r is %r\n" %
 897                                     (remote, s.cipher()))
 898                    sys.stdout.write("Certificate is:\n%s\n" %
 899                                     pprint.pformat(s.getpeercert()))
 900            finally:
 901                s.close()
 902
 903
 904try:
 905    import threading
 906except ImportError:
 907    _have_threads = False
 908else:
 909    _have_threads = True
 910
 911    from test.ssl_servers import make_https_server
 912
 913    class ThreadedEchoServer(threading.Thread):
 914
 915        class ConnectionHandler(threading.Thread):
 916
 917            """A mildly complicated class, because we want it to work both
 918            with and without the SSL wrapper around the socket connection, so
 919            that we can test the STARTTLS functionality."""
 920
 921            def __init__(self, server, connsock, addr):
 922                self.server = server
 923                self.running = False
 924                self.sock = connsock
 925                self.addr = addr
 926                self.sock.setblocking(1)
 927                self.sslconn = None
 928                threading.Thread.__init__(self)
 929                self.daemon = True
 930
 931            def wrap_conn(self):
 932                try:
 933                    self.sslconn = self.server.context.wrap_socket(
 934                        self.sock, server_side=True)
 935                    self.server.selected_protocols.append(self.sslconn.selected_npn_protocol())
 936                except ssl.SSLError as e:
 937                    # XXX Various errors can have happened here, for example
 938                    # a mismatching protocol version, an invalid certificate,
 939                    # or a low-level bug. This should be made more discriminating.
 940                    self.server.conn_errors.append(e)
 941                    if self.server.chatty:
 942                        handle_error("\n server:  bad connection attempt from " + repr(self.addr) + ":\n")
 943                    self.running = False
 944                    self.server.stop()
 945                    self.close()
 946                    return False
 947                else:
 948                    if self.server.context.verify_mode == ssl.CERT_REQUIRED:
 949                        cert = self.sslconn.getpeercert()
 950                        if support.verbose and self.server.chatty:
 951                            sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
 952                        cert_binary = self.sslconn.getpeercert(True)
 953                        if support.verbose and self.server.chatty:
 954                            sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
 955                    cipher = self.sslconn.cipher()
 956                    if support.verbose and self.server.chatty:
 957                        sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
 958                        sys.stdout.write(" server: selected protocol is now "
 959                                + str(self.sslconn.selected_npn_protocol()) + "\n")
 960                    return True
 961
 962            def read(self):
 963                if self.sslconn:
 964                    return self.sslconn.read()
 965                else:
 966                    return self.sock.recv(1024)
 967
 968            def write(self, bytes):
 969                if self.sslconn:
 970                    return self.sslconn.write(bytes)
 971                else:
 972                    return self.sock.send(bytes)
 973
 974            def close(self):
 975                if self.sslconn:
 976                    self.sslconn.close()
 977                else:
 978                    self.sock.close()
 979
 980            def run(self):
 981                self.running = True
 982                if not self.server.starttls_server:
 983                    if not self.wrap_conn():
 984                        return
 985                while self.running:
 986                    try:
 987                        msg = self.read()
 988                        stripped = msg.strip()
 989                        if not stripped:
 990                            # eof, so quit this handler
 991                            self.running = False
 992                            self.close()
 993                        elif stripped == b'over':
 994                            if support.verbose and self.server.connectionchatty:
 995                                sys.stdout.write(" server: client closed connection\n")
 996                            self.close()
 997                            return
 998                        elif (self.server.starttls_server and
 999                              stripped == b'STARTTLS'):
1000                            if support.verbose and self.server.connectionchatty:
1001                                sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
1002                            self.write(b"OK\n")
1003                            if not self.wrap_conn():
1004                                return
1005                        elif (self.server.starttls_server and self.sslconn
1006                              and stripped == b'ENDTLS'):
1007                            if support.verbose and self.server.connectionchatty:
1008                                sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
1009                            self.write(b"OK\n")
1010                            self.sock = self.sslconn.unwrap()
1011                            self.sslconn = None
1012                            if support.verbose and self.server.connectionchatty:
1013                                sys.stdout.write(" server: connection is now unencrypted...\n")
1014                        elif stripped == b'CB tls-unique':
1015                            if support.verbose and self.server.connectionchatty:
1016                                sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
1017                            data = self.sslconn.get_channel_binding("tls-unique")
1018                            self.write(repr(data).encode("us-ascii") + b"\n")
1019                        else:
1020                            if (support.verbose and
1021                                self.server.connectionchatty):
1022                                ctype = (self.sslconn and "encrypted") or "unencrypted"
1023                                sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
1024                                                 % (msg, ctype, msg.lower(), ctype))
1025                            self.write(msg.lower())
1026                    except OSError:
1027                        if self.server.chatty:
1028                            handle_error("Test server failure:\n")
1029                        self.close()
1030                        self.running = False
1031                        # normally, we'd just stop here, but for the test
1032                        # harness, we want to stop the server
1033                        self.server.stop()
1034
1035        def __init__(self, certificate=None, ssl_version=None,
1036                     certreqs=None, cacerts=None,
1037                     chatty=True, connectionchatty=False, starttls_server=False,
1038                     npn_protocols=None, ciphers=None, context=None):
1039            if context:
1040                self.context = context
1041            else:
1042                self.context = ssl.SSLContext(ssl_version
1043                                              if ssl_version is not None
1044                                              else ssl.PROTOCOL_TLSv1)
1045                self.context.verify_mode = (certreqs if certreqs is not None
1046                                            else ssl.CERT_NONE)
1047                if cacerts:
1048                    self.context.load_verify_locations(cacerts)
1049                if certificate:
1050                    self.context.load_cert_chain(certificate)
1051                if npn_protocols:
1052                    self.context.set_npn_protocols(npn_protocols)
1053                if ciphers:
1054                    self.context.set_ciphers(ciphers)
1055            self.chatty = chatty
1056            self.connectionchatty = connectionchatty
1057            self.starttls_server = starttls_server
1058            self.sock = socket.socket()
1059            self.port = support.bind_port(self.sock)
1060            self.flag = None
1061            self.active = False
1062            self.selected_protocols = []
1063            self.conn_errors = []
1064            threading.Thread.__init__(self)
1065            self.daemon = True
1066
1067        def __enter__(self):
1068            self.start(threading.Event())
1069            self.flag.wait()
1070            return self
1071
1072        def __exit__(self, *args):
1073            self.stop()
1074            self.join()
1075
1076        def start(self, flag=None):
1077            self.flag = flag
1078            threading.Thread.start(self)
1079
1080        def run(self):
1081            self.sock.settimeout(0.05)
1082            self.sock.listen(5)
1083            self.active = True
1084            if self.flag:
1085                # signal an event
1086                self.flag.set()
1087            while self.active:
1088                try:
1089                    newconn, connaddr = self.sock.accept()
1090                    if support.verbose and self.chatty:
1091                        sys.stdout.write(' server:  new connection from '
1092                                         + repr(connaddr) + '\n')
1093                    handler = self.ConnectionHandler(self, newconn, connaddr)
1094                    handler.start()
1095                    handler.join()
1096                except socket.timeout:
1097                    pass
1098                except KeyboardInterrupt:
1099                    self.stop()
1100            self.sock.close()
1101
1102        def stop(self):
1103            self.active = False
1104
1105    class AsyncoreEchoServer(threading.Thread):
1106
1107        # this one's based on asyncore.dispatcher
1108
1109        class EchoServer (asyncore.dispatcher):
1110
1111            class ConnectionHandler (asyncore.dispatcher_with_send):
1112
1113                def __init__(self, conn, certfile):
1114                    self.socket = ssl.wrap_socket(conn, server_side=True,
1115                                                  certfile=certfile,
1116                                                  do_handshake_on_connect=False)
1117                    asyncore.dispatcher_with_send.__init__(self, self.socket)
1118                    self._ssl_accepting = True
1119                    self._do_ssl_handshake()
1120
1121                def readable(self):
1122                    if isinstance(self.socket, ssl.SSLSocket):
1123                        while self.socket.pending() > 0:
1124                            self.handle_read_event()
1125                    return True
1126
1127                def _do_ssl_handshake(self):
1128                    try:
1129                        self.socket.do_handshake()
1130                    except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1131                        return
1132                    except ssl.SSLEOFError:
1133                        return self.handle_close()
1134                    except ssl.SSLError:
1135                        raise
1136                    except OSError as err:
1137                        if err.args[0] == errno.ECONNABORTED:
1138                            return self.handle_close()
1139                    else:
1140                        self._ssl_accepting = False
1141
1142                def handle_read(self):
1143                    if self._ssl_accepting:
1144                        self._do_ssl_handshake()
1145                    else:
1146                        data = self.recv(1024)
1147                        if support.verbose:
1148                            sys.stdout.write(" server:  read %s from client\n" % repr(data))
1149                        if not data:
1150                        

Large files files are truncated, but you can click here to view the full file