PageRenderTime 89ms CodeModel.GetById 3ms app.highlight 74ms RepoModel.GetById 2ms app.codeStats 0ms

/Lib/test/test_ssl.py

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

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