PageRenderTime 5ms CodeModel.GetById 23ms app.highlight 106ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_ssl.py

https://bitbucket.org/python_mirrors/releasing-2.7.3
Python | 1900 lines | 1742 code | 83 blank | 75 comment | 91 complexity | ada7ae328deaa1636e2e30bac0863730 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.assertRaisesRegex(ssl.SSLError, "PEM routines"):
 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 NetworkedTests(unittest.TestCase):
 594
 595    def test_connect(self):
 596        with support.transient_internet("svn.python.org"):
 597            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 598                                cert_reqs=ssl.CERT_NONE)
 599            try:
 600                s.connect(("svn.python.org", 443))
 601                self.assertEqual({}, s.getpeercert())
 602            finally:
 603                s.close()
 604
 605            # this should fail because we have no verification certs
 606            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 607                                cert_reqs=ssl.CERT_REQUIRED)
 608            self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
 609                                   s.connect, ("svn.python.org", 443))
 610            s.close()
 611
 612            # this should succeed because we specify the root cert
 613            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 614                                cert_reqs=ssl.CERT_REQUIRED,
 615                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
 616            try:
 617                s.connect(("svn.python.org", 443))
 618                self.assertTrue(s.getpeercert())
 619            finally:
 620                s.close()
 621
 622    def test_connect_ex(self):
 623        # Issue #11326: check connect_ex() implementation
 624        with support.transient_internet("svn.python.org"):
 625            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 626                                cert_reqs=ssl.CERT_REQUIRED,
 627                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
 628            try:
 629                self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
 630                self.assertTrue(s.getpeercert())
 631            finally:
 632                s.close()
 633
 634    def test_non_blocking_connect_ex(self):
 635        # Issue #11326: non-blocking connect_ex() should allow handshake
 636        # to proceed after the socket gets ready.
 637        with support.transient_internet("svn.python.org"):
 638            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 639                                cert_reqs=ssl.CERT_REQUIRED,
 640                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
 641                                do_handshake_on_connect=False)
 642            try:
 643                s.setblocking(False)
 644                rc = s.connect_ex(('svn.python.org', 443))
 645                # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
 646                self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
 647                # Wait for connect to finish
 648                select.select([], [s], [], 5.0)
 649                # Non-blocking handshake
 650                while True:
 651                    try:
 652                        s.do_handshake()
 653                        break
 654                    except ssl.SSLWantReadError:
 655                        select.select([s], [], [], 5.0)
 656                    except ssl.SSLWantWriteError:
 657                        select.select([], [s], [], 5.0)
 658                # SSL established
 659                self.assertTrue(s.getpeercert())
 660            finally:
 661                s.close()
 662
 663    def test_timeout_connect_ex(self):
 664        # Issue #12065: on a timeout, connect_ex() should return the original
 665        # errno (mimicking the behaviour of non-SSL sockets).
 666        with support.transient_internet("svn.python.org"):
 667            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 668                                cert_reqs=ssl.CERT_REQUIRED,
 669                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
 670                                do_handshake_on_connect=False)
 671            try:
 672                s.settimeout(0.0000001)
 673                rc = s.connect_ex(('svn.python.org', 443))
 674                if rc == 0:
 675                    self.skipTest("svn.python.org responded too quickly")
 676                self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
 677            finally:
 678                s.close()
 679
 680    def test_connect_with_context(self):
 681        with support.transient_internet("svn.python.org"):
 682            # Same as test_connect, but with a separately created context
 683            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 684            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 685            s.connect(("svn.python.org", 443))
 686            try:
 687                self.assertEqual({}, s.getpeercert())
 688            finally:
 689                s.close()
 690            # Same with a server hostname
 691            s = ctx.wrap_socket(socket.socket(socket.AF_INET),
 692                                server_hostname="svn.python.org")
 693            if ssl.HAS_SNI:
 694                s.connect(("svn.python.org", 443))
 695                s.close()
 696            else:
 697                self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
 698            # This should fail because we have no verification certs
 699            ctx.verify_mode = ssl.CERT_REQUIRED
 700            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 701            self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
 702                                    s.connect, ("svn.python.org", 443))
 703            s.close()
 704            # This should succeed because we specify the root cert
 705            ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
 706            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 707            s.connect(("svn.python.org", 443))
 708            try:
 709                cert = s.getpeercert()
 710                self.assertTrue(cert)
 711            finally:
 712                s.close()
 713
 714    def test_connect_capath(self):
 715        # Verify server certificates using the `capath` argument
 716        # NOTE: the subject hashing algorithm has been changed between
 717        # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
 718        # contain both versions of each certificate (same content, different
 719        # filename) for this test to be portable across OpenSSL releases.
 720        with support.transient_internet("svn.python.org"):
 721            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 722            ctx.verify_mode = ssl.CERT_REQUIRED
 723            ctx.load_verify_locations(capath=CAPATH)
 724            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 725            s.connect(("svn.python.org", 443))
 726            try:
 727                cert = s.getpeercert()
 728                self.assertTrue(cert)
 729            finally:
 730                s.close()
 731            # Same with a bytes `capath` argument
 732            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 733            ctx.verify_mode = ssl.CERT_REQUIRED
 734            ctx.load_verify_locations(capath=BYTES_CAPATH)
 735            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 736            s.connect(("svn.python.org", 443))
 737            try:
 738                cert = s.getpeercert()
 739                self.assertTrue(cert)
 740            finally:
 741                s.close()
 742
 743    @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
 744    def test_makefile_close(self):
 745        # Issue #5238: creating a file-like object with makefile() shouldn't
 746        # delay closing the underlying "real socket" (here tested with its
 747        # file descriptor, hence skipping the test under Windows).
 748        with support.transient_internet("svn.python.org"):
 749            ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
 750            ss.connect(("svn.python.org", 443))
 751            fd = ss.fileno()
 752            f = ss.makefile()
 753            f.close()
 754            # The fd is still open
 755            os.read(fd, 0)
 756            # Closing the SSL socket should close the fd too
 757            ss.close()
 758            gc.collect()
 759            with self.assertRaises(OSError) as e:
 760                os.read(fd, 0)
 761            self.assertEqual(e.exception.errno, errno.EBADF)
 762
 763    def test_non_blocking_handshake(self):
 764        with support.transient_internet("svn.python.org"):
 765            s = socket.socket(socket.AF_INET)
 766            s.connect(("svn.python.org", 443))
 767            s.setblocking(False)
 768            s = ssl.wrap_socket(s,
 769                                cert_reqs=ssl.CERT_NONE,
 770                                do_handshake_on_connect=False)
 771            count = 0
 772            while True:
 773                try:
 774                    count += 1
 775                    s.do_handshake()
 776                    break
 777                except ssl.SSLWantReadError:
 778                    select.select([s], [], [])
 779                except ssl.SSLWantWriteError:
 780                    select.select([], [s], [])
 781            s.close()
 782            if support.verbose:
 783                sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
 784
 785    def test_get_server_certificate(self):
 786        def _test_get_server_certificate(host, port, cert=None):
 787            with support.transient_internet(host):
 788                pem = ssl.get_server_certificate((host, port))
 789                if not pem:
 790                    self.fail("No server certificate on %s:%s!" % (host, port))
 791
 792                try:
 793                    pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
 794                except ssl.SSLError as x:
 795                    #should fail
 796                    if support.verbose:
 797                        sys.stdout.write("%s\n" % x)
 798                else:
 799                    self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
 800
 801                pem = ssl.get_server_certificate((host, port), ca_certs=cert)
 802                if not pem:
 803                    self.fail("No server certificate on %s:%s!" % (host, port))
 804                if support.verbose:
 805                    sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
 806
 807        _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
 808        if support.IPV6_ENABLED:
 809            _test_get_server_certificate('ipv6.google.com', 443)
 810
 811    def test_ciphers(self):
 812        remote = ("svn.python.org", 443)
 813        with support.transient_internet(remote[0]):
 814            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 815                                cert_reqs=ssl.CERT_NONE, ciphers="ALL")
 816            s.connect(remote)
 817            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 818                                cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
 819            s.connect(remote)
 820            # Error checking can happen at instantiation or when connecting
 821            with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
 822                with socket.socket(socket.AF_INET) as sock:
 823                    s = ssl.wrap_socket(sock,
 824                                        cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
 825                    s.connect(remote)
 826
 827    def test_algorithms(self):
 828        # Issue #8484: all algorithms should be available when verifying a
 829        # certificate.
 830        # SHA256 was added in OpenSSL 0.9.8
 831        if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
 832            self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
 833        # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
 834        remote = ("sha256.tbs-internet.com", 443)
 835        sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
 836        with support.transient_internet("sha256.tbs-internet.com"):
 837            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 838                                cert_reqs=ssl.CERT_REQUIRED,
 839                                ca_certs=sha256_cert,)
 840            try:
 841                s.connect(remote)
 842                if support.verbose:
 843                    sys.stdout.write("\nCipher with %r is %r\n" %
 844                                     (remote, s.cipher()))
 845                    sys.stdout.write("Certificate is:\n%s\n" %
 846                                     pprint.pformat(s.getpeercert()))
 847            finally:
 848                s.close()
 849
 850
 851try:
 852    import threading
 853except ImportError:
 854    _have_threads = False
 855else:
 856    _have_threads = True
 857
 858    from test.ssl_servers import make_https_server
 859
 860    class ThreadedEchoServer(threading.Thread):
 861
 862        class ConnectionHandler(threading.Thread):
 863
 864            """A mildly complicated class, because we want it to work both
 865            with and without the SSL wrapper around the socket connection, so
 866            that we can test the STARTTLS functionality."""
 867
 868            def __init__(self, server, connsock, addr):
 869                self.server = server
 870                self.running = False
 871                self.sock = connsock
 872                self.addr = addr
 873                self.sock.setblocking(1)
 874                self.sslconn = None
 875                threading.Thread.__init__(self)
 876                self.daemon = True
 877
 878            def wrap_conn(self):
 879                try:
 880                    self.sslconn = self.server.context.wrap_socket(
 881                        self.sock, server_side=True)
 882                except ssl.SSLError as e:
 883                    # XXX Various errors can have happened here, for example
 884                    # a mismatching protocol version, an invalid certificate,
 885                    # or a low-level bug. This should be made more discriminating.
 886                    self.server.conn_errors.append(e)
 887                    if self.server.chatty:
 888                        handle_error("\n server:  bad connection attempt from " + repr(self.addr) + ":\n")
 889                    self.running = False
 890                    self.server.stop()
 891                    self.close()
 892                    return False
 893                else:
 894                    if self.server.context.verify_mode == ssl.CERT_REQUIRED:
 895                        cert = self.sslconn.getpeercert()
 896                        if support.verbose and self.server.chatty:
 897                            sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
 898                        cert_binary = self.sslconn.getpeercert(True)
 899                        if support.verbose and self.server.chatty:
 900                            sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
 901                    cipher = self.sslconn.cipher()
 902                    if support.verbose and self.server.chatty:
 903                        sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
 904                    return True
 905
 906            def read(self):
 907                if self.sslconn:
 908                    return self.sslconn.read()
 909                else:
 910                    return self.sock.recv(1024)
 911
 912            def write(self, bytes):
 913                if self.sslconn:
 914                    return self.sslconn.write(bytes)
 915                else:
 916                    return self.sock.send(bytes)
 917
 918            def close(self):
 919                if self.sslconn:
 920                    self.sslconn.close()
 921                else:
 922                    self.sock.close()
 923
 924            def run(self):
 925                self.running = True
 926                if not self.server.starttls_server:
 927                    if not self.wrap_conn():
 928                        return
 929                while self.running:
 930                    try:
 931                        msg = self.read()
 932                        stripped = msg.strip()
 933                        if not stripped:
 934                            # eof, so quit this handler
 935                            self.running = False
 936                            self.close()
 937                        elif stripped == b'over':
 938                            if support.verbose and self.server.connectionchatty:
 939                                sys.stdout.write(" server: client closed connection\n")
 940                            self.close()
 941                            return
 942                        elif (self.server.starttls_server and
 943                              stripped == b'STARTTLS'):
 944                            if support.verbose and self.server.connectionchatty:
 945                                sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
 946                            self.write(b"OK\n")
 947                            if not self.wrap_conn():
 948                                return
 949                        elif (self.server.starttls_server and self.sslconn
 950                              and stripped == b'ENDTLS'):
 951                            if support.verbose and self.server.connectionchatty:
 952                                sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
 953                            self.write(b"OK\n")
 954                            self.sock = self.sslconn.unwrap()
 955                            self.sslconn = None
 956                            if support.verbose and self.server.connectionchatty:
 957                                sys.stdout.write(" server: connection is now unencrypted...\n")
 958                        elif stripped == b'CB tls-unique':
 959                            if support.verbose and self.server.connectionchatty:
 960                                sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
 961                            data = self.sslconn.get_channel_binding("tls-unique")
 962                            self.write(repr(data).encode("us-ascii") + b"\n")
 963                        else:
 964                            if (support.verbose and
 965                                self.server.connectionchatty):
 966                                ctype = (self.sslconn and "encrypted") or "unencrypted"
 967                                sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
 968                                                 % (msg, ctype, msg.lower(), ctype))
 969                            self.write(msg.lower())
 970                    except socket.error:
 971                        if self.server.chatty:
 972                            handle_error("Test server failure:\n")
 973                        self.close()
 974                        self.running = False
 975                        # normally, we'd just stop here, but for the test
 976                        # harness, we want to stop the server
 977                        self.server.stop()
 978
 979        def __init__(self, certificate=None, ssl_version=None,
 980                     certreqs=None, cacerts=None,
 981                     chatty=True, connectionchatty=False, starttls_server=False,
 982                     ciphers=None, context=None):
 983            if context:
 984                self.context = context
 985            else:
 986                self.context = ssl.SSLContext(ssl_version
 987                                              if ssl_version is not None
 988                                              else ssl.PROTOCOL_TLSv1)
 989                self.context.verify_mode = (certreqs if certreqs is not None
 990                                            else ssl.CERT_NONE)
 991                if cacerts:
 992                    self.context.load_verify_locations(cacerts)
 993                if certificate:
 994                    self.context.load_cert_chain(certificate)
 995                if ciphers:
 996                    self.context.set_ciphers(ciphers)
 997            self.chatty = chatty
 998            self.connectionchatty = connectionchatty
 999            self.starttls_server = starttls_server
1000            self.sock = socket.socket()
1001            self.port = support.bind_port(self.sock)
1002            self.flag = None
1003            self.active = False
1004            self.conn_errors = []
1005            threading.Thread.__init__(self)
1006            self.daemon = True
1007
1008        def __enter__(self):
1009            self.start(threading.Event())
1010            self.flag.wait()
1011            return self
1012
1013        def __exit__(self, *args):
1014            self.stop()
1015            self.join()
1016
1017        def start(self, flag=None):
1018            self.flag = flag
1019            threading.Thread.start(self)
1020
1021        def run(self):
1022            self.sock.settimeout(0.05)
1023            self.sock.listen(5)
1024            self.active = True
1025            if self.flag:
1026                # signal an event
1027                self.flag.set()
1028            while self.active:
1029                try:
1030                    newconn, connaddr = self.sock.accept()
1031                    if support.verbose and self.chatty:
1032                        sys.stdout.write(' server:  new connection from '
1033                                         + repr(connaddr) + '\n')
1034                    handler = self.ConnectionHandler(self, newconn, connaddr)
1035                    handler.start()
1036                    handler.join()
1037                except socket.timeout:
1038                    pass
1039                except KeyboardInterrupt:
1040                    self.stop()
1041            self.sock.close()
1042
1043        def stop(self):
1044            self.active = False
1045
1046    class AsyncoreEchoServer(threading.Thread):
1047
1048        # this one's based on asyncore.dispatcher
1049
1050        class EchoServer (asyncore.dispatcher):
1051
1052            class ConnectionHandler (asyncore.dispatcher_with_send):
1053
1054                def __init__(self, conn, certfile):
1055                    self.socket = ssl.wrap_socket(conn, server_side=True,
1056                                                  certfile=certfile,
1057                                                  do_handshake_on_connect=False)
1058                    asyncore.dispatcher_with_send.__init__(self, self.socket)
1059                    self._ssl_accepting = True
1060                    self._do_ssl_handshake()
1061
1062                def readable(self):
1063                    if isinstance(self.socket, ssl.SSLSocket):
1064                        while self.socket.pending() > 0:
1065                            self.handle_read_event()
1066                    return True
1067
1068                def _do_ssl_handshake(self):
1069                    try:
1070                        self.socket.do_handshake()
1071                    except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1072                        return
1073                    except ssl.SSLEOFError:
1074                        return self.handle_close()
1075                    except ssl.SSLError:
1076                        raise
1077                    except socket.error as err:
1078                        if err.args[0] == errno.ECONNABORTED:
1079                            return self.handle_close()
1080                    else:
1081                        self._ssl_accepting = False
1082
1083                def handle_read(self):
1084                    if self._ssl_accepting:
1085                        self._do_ssl_handshake()
1086                    else:
1087                        data = self.recv(1024)
1088                        if support.verbose:
1089                            sys.stdout.write(" server:  read %s from client\n" % repr(data))
1090                        if not data:
1091                            self.close()
1092                        else:
1093                            self.send(data.lower())
1094
1095                def handle_close(self):
1096                    self.close()
1097                    if support.verbose:
1098                        sys.stdout.write(" server:  closed connection %s\n" % self.socket)
1099
1100                def handle_error(self):
1101                    raise
1102
1103            def __init__(self, certfile):
1104                self.certfile = certfile
1105                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1106                self.port = support.bind_port(sock, '')
1107                asyncore.dispatcher.__init__(self, sock)
1108                self.listen(5)
1109
1110            def handle_accepted(self, sock_obj, addr):
1111                if support.verbose:
1112                    sys.stdout.write(" server:  new connection from %s:%s\n" %addr)
1113                self.ConnectionHandler(sock_obj, self.certfile)
1114
1115            def handle_error(self):
1116                raise
1117
1118        def __init__(self, certfile):
1119            self.flag = None
1120            self.active = False
1121            self.server = self.EchoServer(certfile)
1122            self.port = self.server.port
1123            threading.Thread.__init__(self)
1124            self.daemon = True
1125
1126        def __str__(self):
1127            return "<%s %s>" % (self.__class__.__name__, self.server)
1128
1129        def __enter__(self):
1130            self.start(threading.Event())
1131            self.flag.wait()
1132            return self
1133
1134        def __exit__(self, *args):
1135            if support.verbose:
1136                sys.stdout.write(" cleanup: stopping server.\n")
1137            self.stop()
1138            if support.verbose:
1139                sys.stdout.write(" cleanup: joining server thread.\n")
1140            self.join()
1141            if support.verbose:
1142                sys.stdout.write(" cleanup: successfully joined.\n")
1143
1144        def start (self, flag=None):
1145            self.flag = flag
1146            threading.Thread.start(self)
1147
1148        def run(self):
1149            self.active = True
1150            if self.flag:
1151                self.flag.set()
1152            while self.active:
1153                try:
1154                    asyncore.loop(1)
1155                except:
1156                    pass
1157
1158        def stop(self):
1159            self.active = False
1160            self.server.close()
1161
1162    def bad_cert_test(certfile):
1163        """
1164        Launch a server with CERT_REQUIRED, and check that trying to
1165        connect to it with the given client certificate fails.
1166        """
1167        server = ThreadedEchoServer(CERTFILE,
1168                                    certreqs=ssl.CERT_REQUIRED,
1169                                    cacerts=CERTFILE, chatty=False,
1170                                    connectionchatty=False)
1171        with serv

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