PageRenderTime 99ms CodeModel.GetById 3ms app.highlight 85ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_ssl.py

https://bitbucket.org/python_mirrors/sandbox-cjerdonek-cpython
Python | 1988 lines | 1802 code | 94 blank | 92 comment | 101 complexity | 655a6b1b4a0d7a414a150fa6de436163 MD5 | raw file

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

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

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