PageRenderTime 113ms CodeModel.GetById 3ms app.highlight 97ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_ssl.py

https://bitbucket.org/python_mirrors/sandbox-jcea-cpython-2011
Python | 1992 lines | 1822 code | 88 blank | 82 comment | 96 complexity | 7e074840d6d26eaa127cc5f113275e13 MD5 | raw file

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

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

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