PageRenderTime 86ms CodeModel.GetById 3ms app.highlight 71ms RepoModel.GetById 1ms app.codeStats 1ms

/Lib/test/test_ssl.py

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

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