PageRenderTime 10ms CodeModel.GetById 4ms app.highlight 97ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_ssl.py

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

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