PageRenderTime 133ms CodeModel.GetById 3ms app.highlight 115ms RepoModel.GetById 1ms app.codeStats 0ms

/Lib/test/test_ssl.py

https://bitbucket.org/python_mirrors/sandbox-gps-cpython
Python | 1899 lines | 1741 code | 83 blank | 75 comment | 91 complexity | 518d1f974bbe18586ccc47efba56bbcb MD5 | raw file
   1# Test the support for SSL and sockets
   2
   3import sys
   4import unittest
   5from test import support
   6import socket
   7import select
   8import time
   9import gc
  10import os
  11import errno
  12import pprint
  13import tempfile
  14import urllib.request
  15import traceback
  16import asyncore
  17import weakref
  18import platform
  19import functools
  20
  21ssl = support.import_module("ssl")
  22
  23PROTOCOLS = [
  24    ssl.PROTOCOL_SSLv3,
  25    ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1
  26]
  27if hasattr(ssl, 'PROTOCOL_SSLv2'):
  28    PROTOCOLS.append(ssl.PROTOCOL_SSLv2)
  29
  30HOST = support.HOST
  31
  32data_file = lambda name: os.path.join(os.path.dirname(__file__), name)
  33
  34# The custom key and certificate files used in test_ssl are generated
  35# using Lib/test/make_ssl_certs.py.
  36# Other certificates are simply fetched from the Internet servers they
  37# are meant to authenticate.
  38
  39CERTFILE = data_file("keycert.pem")
  40BYTES_CERTFILE = os.fsencode(CERTFILE)
  41ONLYCERT = data_file("ssl_cert.pem")
  42ONLYKEY = data_file("ssl_key.pem")
  43BYTES_ONLYCERT = os.fsencode(ONLYCERT)
  44BYTES_ONLYKEY = os.fsencode(ONLYKEY)
  45CERTFILE_PROTECTED = data_file("keycert.passwd.pem")
  46ONLYKEY_PROTECTED = data_file("ssl_key.passwd.pem")
  47KEY_PASSWORD = "somepass"
  48CAPATH = data_file("capath")
  49BYTES_CAPATH = os.fsencode(CAPATH)
  50
  51SVN_PYTHON_ORG_ROOT_CERT = data_file("https_svn_python_org_root.pem")
  52
  53EMPTYCERT = data_file("nullcert.pem")
  54BADCERT = data_file("badcert.pem")
  55WRONGCERT = data_file("XXXnonexisting.pem")
  56BADKEY = data_file("badkey.pem")
  57NOKIACERT = data_file("nokia.pem")
  58
  59DHFILE = data_file("dh512.pem")
  60BYTES_DHFILE = os.fsencode(DHFILE)
  61
  62def handle_error(prefix):
  63    exc_format = ' '.join(traceback.format_exception(*sys.exc_info()))
  64    if support.verbose:
  65        sys.stdout.write(prefix + exc_format)
  66
  67def can_clear_options():
  68    # 0.9.8m or higher
  69    return ssl._OPENSSL_API_VERSION >= (0, 9, 8, 13, 15)
  70
  71def no_sslv2_implies_sslv3_hello():
  72    # 0.9.7h or higher
  73    return ssl.OPENSSL_VERSION_INFO >= (0, 9, 7, 8, 15)
  74
  75
  76# Issue #9415: Ubuntu hijacks their OpenSSL and forcefully disables SSLv2
  77def skip_if_broken_ubuntu_ssl(func):
  78    if hasattr(ssl, 'PROTOCOL_SSLv2'):
  79        @functools.wraps(func)
  80        def f(*args, **kwargs):
  81            try:
  82                ssl.SSLContext(ssl.PROTOCOL_SSLv2)
  83            except ssl.SSLError:
  84                if (ssl.OPENSSL_VERSION_INFO == (0, 9, 8, 15, 15) and
  85                    platform.linux_distribution() == ('debian', 'squeeze/sid', '')):
  86                    raise unittest.SkipTest("Patched Ubuntu OpenSSL breaks behaviour")
  87            return func(*args, **kwargs)
  88        return f
  89    else:
  90        return func
  91
  92
  93class BasicSocketTests(unittest.TestCase):
  94
  95    def test_constants(self):
  96        #ssl.PROTOCOL_SSLv2
  97        ssl.PROTOCOL_SSLv23
  98        ssl.PROTOCOL_SSLv3
  99        ssl.PROTOCOL_TLSv1
 100        ssl.CERT_NONE
 101        ssl.CERT_OPTIONAL
 102        ssl.CERT_REQUIRED
 103        ssl.OP_CIPHER_SERVER_PREFERENCE
 104        ssl.OP_SINGLE_DH_USE
 105        ssl.OP_SINGLE_ECDH_USE
 106        if ssl.OPENSSL_VERSION_INFO >= (1, 0):
 107            ssl.OP_NO_COMPRESSION
 108        self.assertIn(ssl.HAS_SNI, {True, False})
 109        self.assertIn(ssl.HAS_ECDH, {True, False})
 110
 111    def test_random(self):
 112        v = ssl.RAND_status()
 113        if support.verbose:
 114            sys.stdout.write("\n RAND_status is %d (%s)\n"
 115                             % (v, (v and "sufficient randomness") or
 116                                "insufficient randomness"))
 117
 118        data, is_cryptographic = ssl.RAND_pseudo_bytes(16)
 119        self.assertEqual(len(data), 16)
 120        self.assertEqual(is_cryptographic, v == 1)
 121        if v:
 122            data = ssl.RAND_bytes(16)
 123            self.assertEqual(len(data), 16)
 124        else:
 125            self.assertRaises(ssl.SSLError, ssl.RAND_bytes, 16)
 126
 127        try:
 128            ssl.RAND_egd(1)
 129        except TypeError:
 130            pass
 131        else:
 132            print("didn't raise TypeError")
 133        ssl.RAND_add("this is a random string", 75.0)
 134
 135    def test_parse_cert(self):
 136        # note that this uses an 'unofficial' function in _ssl.c,
 137        # provided solely for this test, to exercise the certificate
 138        # parsing code
 139        p = ssl._ssl._test_decode_cert(CERTFILE)
 140        if support.verbose:
 141            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
 142        self.assertEqual(p['issuer'],
 143                         ((('countryName', 'XY'),),
 144                          (('localityName', 'Castle Anthrax'),),
 145                          (('organizationName', 'Python Software Foundation'),),
 146                          (('commonName', 'localhost'),))
 147                        )
 148        self.assertEqual(p['notAfter'], 'Oct  5 23:01:56 2020 GMT')
 149        self.assertEqual(p['notBefore'], 'Oct  8 23:01:56 2010 GMT')
 150        self.assertEqual(p['serialNumber'], 'D7C7381919AFC24E')
 151        self.assertEqual(p['subject'],
 152                         ((('countryName', 'XY'),),
 153                          (('localityName', 'Castle Anthrax'),),
 154                          (('organizationName', 'Python Software Foundation'),),
 155                          (('commonName', 'localhost'),))
 156                        )
 157        self.assertEqual(p['subjectAltName'], (('DNS', 'localhost'),))
 158        # Issue #13034: the subjectAltName in some certificates
 159        # (notably projects.developer.nokia.com:443) wasn't parsed
 160        p = ssl._ssl._test_decode_cert(NOKIACERT)
 161        if support.verbose:
 162            sys.stdout.write("\n" + pprint.pformat(p) + "\n")
 163        self.assertEqual(p['subjectAltName'],
 164                         (('DNS', 'projects.developer.nokia.com'),
 165                          ('DNS', 'projects.forum.nokia.com'))
 166                        )
 167
 168    def test_DER_to_PEM(self):
 169        with open(SVN_PYTHON_ORG_ROOT_CERT, 'r') as f:
 170            pem = f.read()
 171        d1 = ssl.PEM_cert_to_DER_cert(pem)
 172        p2 = ssl.DER_cert_to_PEM_cert(d1)
 173        d2 = ssl.PEM_cert_to_DER_cert(p2)
 174        self.assertEqual(d1, d2)
 175        if not p2.startswith(ssl.PEM_HEADER + '\n'):
 176            self.fail("DER-to-PEM didn't include correct header:\n%r\n" % p2)
 177        if not p2.endswith('\n' + ssl.PEM_FOOTER + '\n'):
 178            self.fail("DER-to-PEM didn't include correct footer:\n%r\n" % p2)
 179
 180    def test_openssl_version(self):
 181        n = ssl.OPENSSL_VERSION_NUMBER
 182        t = ssl.OPENSSL_VERSION_INFO
 183        s = ssl.OPENSSL_VERSION
 184        self.assertIsInstance(n, int)
 185        self.assertIsInstance(t, tuple)
 186        self.assertIsInstance(s, str)
 187        # Some sanity checks follow
 188        # >= 0.9
 189        self.assertGreaterEqual(n, 0x900000)
 190        # < 2.0
 191        self.assertLess(n, 0x20000000)
 192        major, minor, fix, patch, status = t
 193        self.assertGreaterEqual(major, 0)
 194        self.assertLess(major, 2)
 195        self.assertGreaterEqual(minor, 0)
 196        self.assertLess(minor, 256)
 197        self.assertGreaterEqual(fix, 0)
 198        self.assertLess(fix, 256)
 199        self.assertGreaterEqual(patch, 0)
 200        self.assertLessEqual(patch, 26)
 201        self.assertGreaterEqual(status, 0)
 202        self.assertLessEqual(status, 15)
 203        # Version string as returned by OpenSSL, the format might change
 204        self.assertTrue(s.startswith("OpenSSL {:d}.{:d}.{:d}".format(major, minor, fix)),
 205                        (s, t))
 206
 207    @support.cpython_only
 208    def test_refcycle(self):
 209        # Issue #7943: an SSL object doesn't create reference cycles with
 210        # itself.
 211        s = socket.socket(socket.AF_INET)
 212        ss = ssl.wrap_socket(s)
 213        wr = weakref.ref(ss)
 214        del ss
 215        self.assertEqual(wr(), None)
 216
 217    def test_wrapped_unconnected(self):
 218        # Methods on an unconnected SSLSocket propagate the original
 219        # socket.error raise by the underlying socket object.
 220        s = socket.socket(socket.AF_INET)
 221        ss = ssl.wrap_socket(s)
 222        self.assertRaises(socket.error, ss.recv, 1)
 223        self.assertRaises(socket.error, ss.recv_into, bytearray(b'x'))
 224        self.assertRaises(socket.error, ss.recvfrom, 1)
 225        self.assertRaises(socket.error, ss.recvfrom_into, bytearray(b'x'), 1)
 226        self.assertRaises(socket.error, ss.send, b'x')
 227        self.assertRaises(socket.error, ss.sendto, b'x', ('0.0.0.0', 0))
 228
 229    def test_timeout(self):
 230        # Issue #8524: when creating an SSL socket, the timeout of the
 231        # original socket should be retained.
 232        for timeout in (None, 0.0, 5.0):
 233            s = socket.socket(socket.AF_INET)
 234            s.settimeout(timeout)
 235            ss = ssl.wrap_socket(s)
 236            self.assertEqual(timeout, ss.gettimeout())
 237
 238    def test_errors(self):
 239        sock = socket.socket()
 240        self.assertRaisesRegex(ValueError,
 241                        "certfile must be specified",
 242                        ssl.wrap_socket, sock, keyfile=CERTFILE)
 243        self.assertRaisesRegex(ValueError,
 244                        "certfile must be specified for server-side operations",
 245                        ssl.wrap_socket, sock, server_side=True)
 246        self.assertRaisesRegex(ValueError,
 247                        "certfile must be specified for server-side operations",
 248                        ssl.wrap_socket, sock, server_side=True, certfile="")
 249        s = ssl.wrap_socket(sock, server_side=True, certfile=CERTFILE)
 250        self.assertRaisesRegex(ValueError, "can't connect in server-side mode",
 251                                s.connect, (HOST, 8080))
 252        with self.assertRaises(IOError) as cm:
 253            with socket.socket() as sock:
 254                ssl.wrap_socket(sock, certfile=WRONGCERT)
 255        self.assertEqual(cm.exception.errno, errno.ENOENT)
 256        with self.assertRaises(IOError) as cm:
 257            with socket.socket() as sock:
 258                ssl.wrap_socket(sock, certfile=CERTFILE, keyfile=WRONGCERT)
 259        self.assertEqual(cm.exception.errno, errno.ENOENT)
 260        with self.assertRaises(IOError) as cm:
 261            with socket.socket() as sock:
 262                ssl.wrap_socket(sock, certfile=WRONGCERT, keyfile=WRONGCERT)
 263        self.assertEqual(cm.exception.errno, errno.ENOENT)
 264
 265    def test_match_hostname(self):
 266        def ok(cert, hostname):
 267            ssl.match_hostname(cert, hostname)
 268        def fail(cert, hostname):
 269            self.assertRaises(ssl.CertificateError,
 270                              ssl.match_hostname, cert, hostname)
 271
 272        cert = {'subject': ((('commonName', 'example.com'),),)}
 273        ok(cert, 'example.com')
 274        ok(cert, 'ExAmple.cOm')
 275        fail(cert, 'www.example.com')
 276        fail(cert, '.example.com')
 277        fail(cert, 'example.org')
 278        fail(cert, 'exampleXcom')
 279
 280        cert = {'subject': ((('commonName', '*.a.com'),),)}
 281        ok(cert, 'foo.a.com')
 282        fail(cert, 'bar.foo.a.com')
 283        fail(cert, 'a.com')
 284        fail(cert, 'Xa.com')
 285        fail(cert, '.a.com')
 286
 287        cert = {'subject': ((('commonName', 'a.*.com'),),)}
 288        ok(cert, 'a.foo.com')
 289        fail(cert, 'a..com')
 290        fail(cert, 'a.com')
 291
 292        cert = {'subject': ((('commonName', 'f*.com'),),)}
 293        ok(cert, 'foo.com')
 294        ok(cert, 'f.com')
 295        fail(cert, 'bar.com')
 296        fail(cert, 'foo.a.com')
 297        fail(cert, 'bar.foo.com')
 298
 299        # Slightly fake real-world example
 300        cert = {'notAfter': 'Jun 26 21:41:46 2011 GMT',
 301                'subject': ((('commonName', 'linuxfrz.org'),),),
 302                'subjectAltName': (('DNS', 'linuxfr.org'),
 303                                   ('DNS', 'linuxfr.com'),
 304                                   ('othername', '<unsupported>'))}
 305        ok(cert, 'linuxfr.org')
 306        ok(cert, 'linuxfr.com')
 307        # Not a "DNS" entry
 308        fail(cert, '<unsupported>')
 309        # When there is a subjectAltName, commonName isn't used
 310        fail(cert, 'linuxfrz.org')
 311
 312        # A pristine real-world example
 313        cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
 314                'subject': ((('countryName', 'US'),),
 315                            (('stateOrProvinceName', 'California'),),
 316                            (('localityName', 'Mountain View'),),
 317                            (('organizationName', 'Google Inc'),),
 318                            (('commonName', 'mail.google.com'),))}
 319        ok(cert, 'mail.google.com')
 320        fail(cert, 'gmail.com')
 321        # Only commonName is considered
 322        fail(cert, 'California')
 323
 324        # Neither commonName nor subjectAltName
 325        cert = {'notAfter': 'Dec 18 23:59:59 2011 GMT',
 326                'subject': ((('countryName', 'US'),),
 327                            (('stateOrProvinceName', 'California'),),
 328                            (('localityName', 'Mountain View'),),
 329                            (('organizationName', 'Google Inc'),))}
 330        fail(cert, 'mail.google.com')
 331
 332        # No DNS entry in subjectAltName but a commonName
 333        cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
 334                'subject': ((('countryName', 'US'),),
 335                            (('stateOrProvinceName', 'California'),),
 336                            (('localityName', 'Mountain View'),),
 337                            (('commonName', 'mail.google.com'),)),
 338                'subjectAltName': (('othername', 'blabla'), )}
 339        ok(cert, 'mail.google.com')
 340
 341        # No DNS entry subjectAltName and no commonName
 342        cert = {'notAfter': 'Dec 18 23:59:59 2099 GMT',
 343                'subject': ((('countryName', 'US'),),
 344                            (('stateOrProvinceName', 'California'),),
 345                            (('localityName', 'Mountain View'),),
 346                            (('organizationName', 'Google Inc'),)),
 347                'subjectAltName': (('othername', 'blabla'),)}
 348        fail(cert, 'google.com')
 349
 350        # Empty cert / no cert
 351        self.assertRaises(ValueError, ssl.match_hostname, None, 'example.com')
 352        self.assertRaises(ValueError, ssl.match_hostname, {}, 'example.com')
 353
 354    def test_server_side(self):
 355        # server_hostname doesn't work for server sockets
 356        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 357        with socket.socket() as sock:
 358            self.assertRaises(ValueError, ctx.wrap_socket, sock, True,
 359                              server_hostname="some.hostname")
 360
 361    def test_unknown_channel_binding(self):
 362        # should raise ValueError for unknown type
 363        s = socket.socket(socket.AF_INET)
 364        ss = ssl.wrap_socket(s)
 365        with self.assertRaises(ValueError):
 366            ss.get_channel_binding("unknown-type")
 367
 368    @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
 369                         "'tls-unique' channel binding not available")
 370    def test_tls_unique_channel_binding(self):
 371        # unconnected should return None for known type
 372        s = socket.socket(socket.AF_INET)
 373        ss = ssl.wrap_socket(s)
 374        self.assertIsNone(ss.get_channel_binding("tls-unique"))
 375        # the same for server-side
 376        s = socket.socket(socket.AF_INET)
 377        ss = ssl.wrap_socket(s, server_side=True, certfile=CERTFILE)
 378        self.assertIsNone(ss.get_channel_binding("tls-unique"))
 379
 380class ContextTests(unittest.TestCase):
 381
 382    @skip_if_broken_ubuntu_ssl
 383    def test_constructor(self):
 384        if hasattr(ssl, 'PROTOCOL_SSLv2'):
 385            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv2)
 386        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 387        ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv3)
 388        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 389        self.assertRaises(TypeError, ssl.SSLContext)
 390        self.assertRaises(ValueError, ssl.SSLContext, -1)
 391        self.assertRaises(ValueError, ssl.SSLContext, 42)
 392
 393    @skip_if_broken_ubuntu_ssl
 394    def test_protocol(self):
 395        for proto in PROTOCOLS:
 396            ctx = ssl.SSLContext(proto)
 397            self.assertEqual(ctx.protocol, proto)
 398
 399    def test_ciphers(self):
 400        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 401        ctx.set_ciphers("ALL")
 402        ctx.set_ciphers("DEFAULT")
 403        with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
 404            ctx.set_ciphers("^$:,;?*'dorothyx")
 405
 406    @skip_if_broken_ubuntu_ssl
 407    def test_options(self):
 408        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 409        # OP_ALL is the default value
 410        self.assertEqual(ssl.OP_ALL, ctx.options)
 411        ctx.options |= ssl.OP_NO_SSLv2
 412        self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2,
 413                         ctx.options)
 414        ctx.options |= ssl.OP_NO_SSLv3
 415        self.assertEqual(ssl.OP_ALL | ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3,
 416                         ctx.options)
 417        if can_clear_options():
 418            ctx.options = (ctx.options & ~ssl.OP_NO_SSLv2) | ssl.OP_NO_TLSv1
 419            self.assertEqual(ssl.OP_ALL | ssl.OP_NO_TLSv1 | ssl.OP_NO_SSLv3,
 420                             ctx.options)
 421            ctx.options = 0
 422            self.assertEqual(0, ctx.options)
 423        else:
 424            with self.assertRaises(ValueError):
 425                ctx.options = 0
 426
 427    def test_verify(self):
 428        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 429        # Default value
 430        self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
 431        ctx.verify_mode = ssl.CERT_OPTIONAL
 432        self.assertEqual(ctx.verify_mode, ssl.CERT_OPTIONAL)
 433        ctx.verify_mode = ssl.CERT_REQUIRED
 434        self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
 435        ctx.verify_mode = ssl.CERT_NONE
 436        self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
 437        with self.assertRaises(TypeError):
 438            ctx.verify_mode = None
 439        with self.assertRaises(ValueError):
 440            ctx.verify_mode = 42
 441
 442    def test_load_cert_chain(self):
 443        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 444        # Combined key and cert in a single file
 445        ctx.load_cert_chain(CERTFILE)
 446        ctx.load_cert_chain(CERTFILE, keyfile=CERTFILE)
 447        self.assertRaises(TypeError, ctx.load_cert_chain, keyfile=CERTFILE)
 448        with self.assertRaises(IOError) as cm:
 449            ctx.load_cert_chain(WRONGCERT)
 450        self.assertEqual(cm.exception.errno, errno.ENOENT)
 451        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 452            ctx.load_cert_chain(BADCERT)
 453        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 454            ctx.load_cert_chain(EMPTYCERT)
 455        # Separate key and cert
 456        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 457        ctx.load_cert_chain(ONLYCERT, ONLYKEY)
 458        ctx.load_cert_chain(certfile=ONLYCERT, keyfile=ONLYKEY)
 459        ctx.load_cert_chain(certfile=BYTES_ONLYCERT, keyfile=BYTES_ONLYKEY)
 460        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 461            ctx.load_cert_chain(ONLYCERT)
 462        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 463            ctx.load_cert_chain(ONLYKEY)
 464        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 465            ctx.load_cert_chain(certfile=ONLYKEY, keyfile=ONLYCERT)
 466        # Mismatching key and cert
 467        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 468        with self.assertRaisesRegex(ssl.SSLError, "key values mismatch"):
 469            ctx.load_cert_chain(SVN_PYTHON_ORG_ROOT_CERT, ONLYKEY)
 470        # Password protected key and cert
 471        ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD)
 472        ctx.load_cert_chain(CERTFILE_PROTECTED, password=KEY_PASSWORD.encode())
 473        ctx.load_cert_chain(CERTFILE_PROTECTED,
 474                            password=bytearray(KEY_PASSWORD.encode()))
 475        ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD)
 476        ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED, KEY_PASSWORD.encode())
 477        ctx.load_cert_chain(ONLYCERT, ONLYKEY_PROTECTED,
 478                            bytearray(KEY_PASSWORD.encode()))
 479        with self.assertRaisesRegex(TypeError, "should be a string"):
 480            ctx.load_cert_chain(CERTFILE_PROTECTED, password=True)
 481        with self.assertRaises(ssl.SSLError):
 482            ctx.load_cert_chain(CERTFILE_PROTECTED, password="badpass")
 483        with self.assertRaisesRegex(ValueError, "cannot be longer"):
 484            # openssl has a fixed limit on the password buffer.
 485            # PEM_BUFSIZE is generally set to 1kb.
 486            # Return a string larger than this.
 487            ctx.load_cert_chain(CERTFILE_PROTECTED, password=b'a' * 102400)
 488        # Password callback
 489        def getpass_unicode():
 490            return KEY_PASSWORD
 491        def getpass_bytes():
 492            return KEY_PASSWORD.encode()
 493        def getpass_bytearray():
 494            return bytearray(KEY_PASSWORD.encode())
 495        def getpass_badpass():
 496            return "badpass"
 497        def getpass_huge():
 498            return b'a' * (1024 * 1024)
 499        def getpass_bad_type():
 500            return 9
 501        def getpass_exception():
 502            raise Exception('getpass error')
 503        class GetPassCallable:
 504            def __call__(self):
 505                return KEY_PASSWORD
 506            def getpass(self):
 507                return KEY_PASSWORD
 508        ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_unicode)
 509        ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytes)
 510        ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bytearray)
 511        ctx.load_cert_chain(CERTFILE_PROTECTED, password=GetPassCallable())
 512        ctx.load_cert_chain(CERTFILE_PROTECTED,
 513                            password=GetPassCallable().getpass)
 514        with self.assertRaises(ssl.SSLError):
 515            ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_badpass)
 516        with self.assertRaisesRegex(ValueError, "cannot be longer"):
 517            ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_huge)
 518        with self.assertRaisesRegex(TypeError, "must return a string"):
 519            ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_bad_type)
 520        with self.assertRaisesRegex(Exception, "getpass error"):
 521            ctx.load_cert_chain(CERTFILE_PROTECTED, password=getpass_exception)
 522        # Make sure the password function isn't called if it isn't needed
 523        ctx.load_cert_chain(CERTFILE, password=getpass_exception)
 524
 525    def test_load_verify_locations(self):
 526        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 527        ctx.load_verify_locations(CERTFILE)
 528        ctx.load_verify_locations(cafile=CERTFILE, capath=None)
 529        ctx.load_verify_locations(BYTES_CERTFILE)
 530        ctx.load_verify_locations(cafile=BYTES_CERTFILE, capath=None)
 531        self.assertRaises(TypeError, ctx.load_verify_locations)
 532        self.assertRaises(TypeError, ctx.load_verify_locations, None, None)
 533        with self.assertRaises(IOError) as cm:
 534            ctx.load_verify_locations(WRONGCERT)
 535        self.assertEqual(cm.exception.errno, errno.ENOENT)
 536        with self.assertRaisesRegex(ssl.SSLError, "PEM lib"):
 537            ctx.load_verify_locations(BADCERT)
 538        ctx.load_verify_locations(CERTFILE, CAPATH)
 539        ctx.load_verify_locations(CERTFILE, capath=BYTES_CAPATH)
 540
 541        # Issue #10989: crash if the second argument type is invalid
 542        self.assertRaises(TypeError, ctx.load_verify_locations, None, True)
 543
 544    def test_load_dh_params(self):
 545        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 546        ctx.load_dh_params(DHFILE)
 547        if os.name != 'nt':
 548            ctx.load_dh_params(BYTES_DHFILE)
 549        self.assertRaises(TypeError, ctx.load_dh_params)
 550        self.assertRaises(TypeError, ctx.load_dh_params, None)
 551        with self.assertRaises(FileNotFoundError) as cm:
 552            ctx.load_dh_params(WRONGCERT)
 553        self.assertEqual(cm.exception.errno, errno.ENOENT)
 554        with self.assertRaisesRegex(ssl.SSLError, "PEM routines"):
 555            ctx.load_dh_params(CERTFILE)
 556
 557    @skip_if_broken_ubuntu_ssl
 558    def test_session_stats(self):
 559        for proto in PROTOCOLS:
 560            ctx = ssl.SSLContext(proto)
 561            self.assertEqual(ctx.session_stats(), {
 562                'number': 0,
 563                'connect': 0,
 564                'connect_good': 0,
 565                'connect_renegotiate': 0,
 566                'accept': 0,
 567                'accept_good': 0,
 568                'accept_renegotiate': 0,
 569                'hits': 0,
 570                'misses': 0,
 571                'timeouts': 0,
 572                'cache_full': 0,
 573            })
 574
 575    def test_set_default_verify_paths(self):
 576        # There's not much we can do to test that it acts as expected,
 577        # so just check it doesn't crash or raise an exception.
 578        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 579        ctx.set_default_verify_paths()
 580
 581    @unittest.skipUnless(ssl.HAS_ECDH, "ECDH disabled on this OpenSSL build")
 582    def test_set_ecdh_curve(self):
 583        ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
 584        ctx.set_ecdh_curve("prime256v1")
 585        ctx.set_ecdh_curve(b"prime256v1")
 586        self.assertRaises(TypeError, ctx.set_ecdh_curve)
 587        self.assertRaises(TypeError, ctx.set_ecdh_curve, None)
 588        self.assertRaises(ValueError, ctx.set_ecdh_curve, "foo")
 589        self.assertRaises(ValueError, ctx.set_ecdh_curve, b"foo")
 590
 591
 592class NetworkedTests(unittest.TestCase):
 593
 594    def test_connect(self):
 595        with support.transient_internet("svn.python.org"):
 596            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 597                                cert_reqs=ssl.CERT_NONE)
 598            try:
 599                s.connect(("svn.python.org", 443))
 600                self.assertEqual({}, s.getpeercert())
 601            finally:
 602                s.close()
 603
 604            # this should fail because we have no verification certs
 605            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 606                                cert_reqs=ssl.CERT_REQUIRED)
 607            self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
 608                                   s.connect, ("svn.python.org", 443))
 609            s.close()
 610
 611            # this should succeed because we specify the root cert
 612            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 613                                cert_reqs=ssl.CERT_REQUIRED,
 614                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
 615            try:
 616                s.connect(("svn.python.org", 443))
 617                self.assertTrue(s.getpeercert())
 618            finally:
 619                s.close()
 620
 621    def test_connect_ex(self):
 622        # Issue #11326: check connect_ex() implementation
 623        with support.transient_internet("svn.python.org"):
 624            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 625                                cert_reqs=ssl.CERT_REQUIRED,
 626                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT)
 627            try:
 628                self.assertEqual(0, s.connect_ex(("svn.python.org", 443)))
 629                self.assertTrue(s.getpeercert())
 630            finally:
 631                s.close()
 632
 633    def test_non_blocking_connect_ex(self):
 634        # Issue #11326: non-blocking connect_ex() should allow handshake
 635        # to proceed after the socket gets ready.
 636        with support.transient_internet("svn.python.org"):
 637            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 638                                cert_reqs=ssl.CERT_REQUIRED,
 639                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
 640                                do_handshake_on_connect=False)
 641            try:
 642                s.setblocking(False)
 643                rc = s.connect_ex(('svn.python.org', 443))
 644                # EWOULDBLOCK under Windows, EINPROGRESS elsewhere
 645                self.assertIn(rc, (0, errno.EINPROGRESS, errno.EWOULDBLOCK))
 646                # Wait for connect to finish
 647                select.select([], [s], [], 5.0)
 648                # Non-blocking handshake
 649                while True:
 650                    try:
 651                        s.do_handshake()
 652                        break
 653                    except ssl.SSLWantReadError:
 654                        select.select([s], [], [], 5.0)
 655                    except ssl.SSLWantWriteError:
 656                        select.select([], [s], [], 5.0)
 657                # SSL established
 658                self.assertTrue(s.getpeercert())
 659            finally:
 660                s.close()
 661
 662    def test_timeout_connect_ex(self):
 663        # Issue #12065: on a timeout, connect_ex() should return the original
 664        # errno (mimicking the behaviour of non-SSL sockets).
 665        with support.transient_internet("svn.python.org"):
 666            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 667                                cert_reqs=ssl.CERT_REQUIRED,
 668                                ca_certs=SVN_PYTHON_ORG_ROOT_CERT,
 669                                do_handshake_on_connect=False)
 670            try:
 671                s.settimeout(0.0000001)
 672                rc = s.connect_ex(('svn.python.org', 443))
 673                if rc == 0:
 674                    self.skipTest("svn.python.org responded too quickly")
 675                self.assertIn(rc, (errno.EAGAIN, errno.EWOULDBLOCK))
 676            finally:
 677                s.close()
 678
 679    def test_connect_with_context(self):
 680        with support.transient_internet("svn.python.org"):
 681            # Same as test_connect, but with a separately created context
 682            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 683            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 684            s.connect(("svn.python.org", 443))
 685            try:
 686                self.assertEqual({}, s.getpeercert())
 687            finally:
 688                s.close()
 689            # Same with a server hostname
 690            s = ctx.wrap_socket(socket.socket(socket.AF_INET),
 691                                server_hostname="svn.python.org")
 692            if ssl.HAS_SNI:
 693                s.connect(("svn.python.org", 443))
 694                s.close()
 695            else:
 696                self.assertRaises(ValueError, s.connect, ("svn.python.org", 443))
 697            # This should fail because we have no verification certs
 698            ctx.verify_mode = ssl.CERT_REQUIRED
 699            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 700            self.assertRaisesRegex(ssl.SSLError, "certificate verify failed",
 701                                    s.connect, ("svn.python.org", 443))
 702            s.close()
 703            # This should succeed because we specify the root cert
 704            ctx.load_verify_locations(SVN_PYTHON_ORG_ROOT_CERT)
 705            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 706            s.connect(("svn.python.org", 443))
 707            try:
 708                cert = s.getpeercert()
 709                self.assertTrue(cert)
 710            finally:
 711                s.close()
 712
 713    def test_connect_capath(self):
 714        # Verify server certificates using the `capath` argument
 715        # NOTE: the subject hashing algorithm has been changed between
 716        # OpenSSL 0.9.8n and 1.0.0, as a result the capath directory must
 717        # contain both versions of each certificate (same content, different
 718        # filename) for this test to be portable across OpenSSL releases.
 719        with support.transient_internet("svn.python.org"):
 720            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 721            ctx.verify_mode = ssl.CERT_REQUIRED
 722            ctx.load_verify_locations(capath=CAPATH)
 723            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 724            s.connect(("svn.python.org", 443))
 725            try:
 726                cert = s.getpeercert()
 727                self.assertTrue(cert)
 728            finally:
 729                s.close()
 730            # Same with a bytes `capath` argument
 731            ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
 732            ctx.verify_mode = ssl.CERT_REQUIRED
 733            ctx.load_verify_locations(capath=BYTES_CAPATH)
 734            s = ctx.wrap_socket(socket.socket(socket.AF_INET))
 735            s.connect(("svn.python.org", 443))
 736            try:
 737                cert = s.getpeercert()
 738                self.assertTrue(cert)
 739            finally:
 740                s.close()
 741
 742    @unittest.skipIf(os.name == "nt", "Can't use a socket as a file under Windows")
 743    def test_makefile_close(self):
 744        # Issue #5238: creating a file-like object with makefile() shouldn't
 745        # delay closing the underlying "real socket" (here tested with its
 746        # file descriptor, hence skipping the test under Windows).
 747        with support.transient_internet("svn.python.org"):
 748            ss = ssl.wrap_socket(socket.socket(socket.AF_INET))
 749            ss.connect(("svn.python.org", 443))
 750            fd = ss.fileno()
 751            f = ss.makefile()
 752            f.close()
 753            # The fd is still open
 754            os.read(fd, 0)
 755            # Closing the SSL socket should close the fd too
 756            ss.close()
 757            gc.collect()
 758            with self.assertRaises(OSError) as e:
 759                os.read(fd, 0)
 760            self.assertEqual(e.exception.errno, errno.EBADF)
 761
 762    def test_non_blocking_handshake(self):
 763        with support.transient_internet("svn.python.org"):
 764            s = socket.socket(socket.AF_INET)
 765            s.connect(("svn.python.org", 443))
 766            s.setblocking(False)
 767            s = ssl.wrap_socket(s,
 768                                cert_reqs=ssl.CERT_NONE,
 769                                do_handshake_on_connect=False)
 770            count = 0
 771            while True:
 772                try:
 773                    count += 1
 774                    s.do_handshake()
 775                    break
 776                except ssl.SSLWantReadError:
 777                    select.select([s], [], [])
 778                except ssl.SSLWantWriteError:
 779                    select.select([], [s], [])
 780            s.close()
 781            if support.verbose:
 782                sys.stdout.write("\nNeeded %d calls to do_handshake() to establish session.\n" % count)
 783
 784    def test_get_server_certificate(self):
 785        def _test_get_server_certificate(host, port, cert=None):
 786            with support.transient_internet(host):
 787                pem = ssl.get_server_certificate((host, port))
 788                if not pem:
 789                    self.fail("No server certificate on %s:%s!" % (host, port))
 790
 791                try:
 792                    pem = ssl.get_server_certificate((host, port), ca_certs=CERTFILE)
 793                except ssl.SSLError as x:
 794                    #should fail
 795                    if support.verbose:
 796                        sys.stdout.write("%s\n" % x)
 797                else:
 798                    self.fail("Got server certificate %s for %s:%s!" % (pem, host, port))
 799
 800                pem = ssl.get_server_certificate((host, port), ca_certs=cert)
 801                if not pem:
 802                    self.fail("No server certificate on %s:%s!" % (host, port))
 803                if support.verbose:
 804                    sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port ,pem))
 805
 806        _test_get_server_certificate('svn.python.org', 443, SVN_PYTHON_ORG_ROOT_CERT)
 807        if support.IPV6_ENABLED:
 808            _test_get_server_certificate('ipv6.google.com', 443)
 809
 810    def test_ciphers(self):
 811        remote = ("svn.python.org", 443)
 812        with support.transient_internet(remote[0]):
 813            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 814                                cert_reqs=ssl.CERT_NONE, ciphers="ALL")
 815            s.connect(remote)
 816            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 817                                cert_reqs=ssl.CERT_NONE, ciphers="DEFAULT")
 818            s.connect(remote)
 819            # Error checking can happen at instantiation or when connecting
 820            with self.assertRaisesRegex(ssl.SSLError, "No cipher can be selected"):
 821                with socket.socket(socket.AF_INET) as sock:
 822                    s = ssl.wrap_socket(sock,
 823                                        cert_reqs=ssl.CERT_NONE, ciphers="^$:,;?*'dorothyx")
 824                    s.connect(remote)
 825
 826    def test_algorithms(self):
 827        # Issue #8484: all algorithms should be available when verifying a
 828        # certificate.
 829        # SHA256 was added in OpenSSL 0.9.8
 830        if ssl.OPENSSL_VERSION_INFO < (0, 9, 8, 0, 15):
 831            self.skipTest("SHA256 not available on %r" % ssl.OPENSSL_VERSION)
 832        # https://sha2.hboeck.de/ was used until 2011-01-08 (no route to host)
 833        remote = ("sha256.tbs-internet.com", 443)
 834        sha256_cert = os.path.join(os.path.dirname(__file__), "sha256.pem")
 835        with support.transient_internet("sha256.tbs-internet.com"):
 836            s = ssl.wrap_socket(socket.socket(socket.AF_INET),
 837                                cert_reqs=ssl.CERT_REQUIRED,
 838                                ca_certs=sha256_cert,)
 839            try:
 840                s.connect(remote)
 841                if support.verbose:
 842                    sys.stdout.write("\nCipher with %r is %r\n" %
 843                                     (remote, s.cipher()))
 844                    sys.stdout.write("Certificate is:\n%s\n" %
 845                                     pprint.pformat(s.getpeercert()))
 846            finally:
 847                s.close()
 848
 849
 850try:
 851    import threading
 852except ImportError:
 853    _have_threads = False
 854else:
 855    _have_threads = True
 856
 857    from test.ssl_servers import make_https_server
 858
 859    class ThreadedEchoServer(threading.Thread):
 860
 861        class ConnectionHandler(threading.Thread):
 862
 863            """A mildly complicated class, because we want it to work both
 864            with and without the SSL wrapper around the socket connection, so
 865            that we can test the STARTTLS functionality."""
 866
 867            def __init__(self, server, connsock, addr):
 868                self.server = server
 869                self.running = False
 870                self.sock = connsock
 871                self.addr = addr
 872                self.sock.setblocking(1)
 873                self.sslconn = None
 874                threading.Thread.__init__(self)
 875                self.daemon = True
 876
 877            def wrap_conn(self):
 878                try:
 879                    self.sslconn = self.server.context.wrap_socket(
 880                        self.sock, server_side=True)
 881                except ssl.SSLError as e:
 882                    # XXX Various errors can have happened here, for example
 883                    # a mismatching protocol version, an invalid certificate,
 884                    # or a low-level bug. This should be made more discriminating.
 885                    self.server.conn_errors.append(e)
 886                    if self.server.chatty:
 887                        handle_error("\n server:  bad connection attempt from " + repr(self.addr) + ":\n")
 888                    self.running = False
 889                    self.server.stop()
 890                    self.close()
 891                    return False
 892                else:
 893                    if self.server.context.verify_mode == ssl.CERT_REQUIRED:
 894                        cert = self.sslconn.getpeercert()
 895                        if support.verbose and self.server.chatty:
 896                            sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
 897                        cert_binary = self.sslconn.getpeercert(True)
 898                        if support.verbose and self.server.chatty:
 899                            sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n")
 900                    cipher = self.sslconn.cipher()
 901                    if support.verbose and self.server.chatty:
 902                        sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
 903                    return True
 904
 905            def read(self):
 906                if self.sslconn:
 907                    return self.sslconn.read()
 908                else:
 909                    return self.sock.recv(1024)
 910
 911            def write(self, bytes):
 912                if self.sslconn:
 913                    return self.sslconn.write(bytes)
 914                else:
 915                    return self.sock.send(bytes)
 916
 917            def close(self):
 918                if self.sslconn:
 919                    self.sslconn.close()
 920                else:
 921                    self.sock.close()
 922
 923            def run(self):
 924                self.running = True
 925                if not self.server.starttls_server:
 926                    if not self.wrap_conn():
 927                        return
 928                while self.running:
 929                    try:
 930                        msg = self.read()
 931                        stripped = msg.strip()
 932                        if not stripped:
 933                            # eof, so quit this handler
 934                            self.running = False
 935                            self.close()
 936                        elif stripped == b'over':
 937                            if support.verbose and self.server.connectionchatty:
 938                                sys.stdout.write(" server: client closed connection\n")
 939                            self.close()
 940                            return
 941                        elif (self.server.starttls_server and
 942                              stripped == b'STARTTLS'):
 943                            if support.verbose and self.server.connectionchatty:
 944                                sys.stdout.write(" server: read STARTTLS from client, sending OK...\n")
 945                            self.write(b"OK\n")
 946                            if not self.wrap_conn():
 947                                return
 948                        elif (self.server.starttls_server and self.sslconn
 949                              and stripped == b'ENDTLS'):
 950                            if support.verbose and self.server.connectionchatty:
 951                                sys.stdout.write(" server: read ENDTLS from client, sending OK...\n")
 952                            self.write(b"OK\n")
 953                            self.sock = self.sslconn.unwrap()
 954                            self.sslconn = None
 955                            if support.verbose and self.server.connectionchatty:
 956                                sys.stdout.write(" server: connection is now unencrypted...\n")
 957                        elif stripped == b'CB tls-unique':
 958                            if support.verbose and self.server.connectionchatty:
 959                                sys.stdout.write(" server: read CB tls-unique from client, sending our CB data...\n")
 960                            data = self.sslconn.get_channel_binding("tls-unique")
 961                            self.write(repr(data).encode("us-ascii") + b"\n")
 962                        else:
 963                            if (support.verbose and
 964                                self.server.connectionchatty):
 965                                ctype = (self.sslconn and "encrypted") or "unencrypted"
 966                                sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
 967                                                 % (msg, ctype, msg.lower(), ctype))
 968                            self.write(msg.lower())
 969                    except socket.error:
 970                        if self.server.chatty:
 971                            handle_error("Test server failure:\n")
 972                        self.close()
 973                        self.running = False
 974                        # normally, we'd just stop here, but for the test
 975                        # harness, we want to stop the server
 976                        self.server.stop()
 977
 978        def __init__(self, certificate=None, ssl_version=None,
 979                     certreqs=None, cacerts=None,
 980                     chatty=True, connectionchatty=False, starttls_server=False,
 981                     ciphers=None, context=None):
 982            if context:
 983                self.context = context
 984            else:
 985                self.context = ssl.SSLContext(ssl_version
 986                                              if ssl_version is not None
 987                                              else ssl.PROTOCOL_TLSv1)
 988                self.context.verify_mode = (certreqs if certreqs is not None
 989                                            else ssl.CERT_NONE)
 990                if cacerts:
 991                    self.context.load_verify_locations(cacerts)
 992                if certificate:
 993                    self.context.load_cert_chain(certificate)
 994                if ciphers:
 995                    self.context.set_ciphers(ciphers)
 996            self.chatty = chatty
 997            self.connectionchatty = connectionchatty
 998            self.starttls_server = starttls_server
 999            self.sock = socket.socket()
1000            self.port = support.bind_port(self.sock)
1001            self.flag = None
1002            self.active = False
1003            self.conn_errors = []
1004            threading.Thread.__init__(self)
1005            self.daemon = True
1006
1007        def __enter__(self):
1008            self.start(threading.Event())
1009            self.flag.wait()
1010            return self
1011
1012        def __exit__(self, *args):
1013            self.stop()
1014            self.join()
1015
1016        def start(self, flag=None):
1017            self.flag = flag
1018            threading.Thread.start(self)
1019
1020        def run(self):
1021            self.sock.settimeout(0.05)
1022            self.sock.listen(5)
1023            self.active = True
1024            if self.flag:
1025                # signal an event
1026                self.flag.set()
1027            while self.active:
1028                try:
1029                    newconn, connaddr = self.sock.accept()
1030                    if support.verbose and self.chatty:
1031                        sys.stdout.write(' server:  new connection from '
1032                                         + repr(connaddr) + '\n')
1033                    handler = self.ConnectionHandler(self, newconn, connaddr)
1034                    handler.start()
1035                    handler.join()
1036                except socket.timeout:
1037                    pass
1038                except KeyboardInterrupt:
1039                    self.stop()
1040            self.sock.close()
1041
1042        def stop(self):
1043            self.active = False
1044
1045    class AsyncoreEchoServer(threading.Thread):
1046
1047        # this one's based on asyncore.dispatcher
1048
1049        class EchoServer (asyncore.dispatcher):
1050
1051            class ConnectionHandler (asyncore.dispatcher_with_send):
1052
1053                def __init__(self, conn, certfile):
1054                    self.socket = ssl.wrap_socket(conn, server_side=True,
1055                                                  certfile=certfile,
1056                                                  do_handshake_on_connect=False)
1057                    asyncore.dispatcher_with_send.__init__(self, self.socket)
1058                    self._ssl_accepting = True
1059                    self._do_ssl_handshake()
1060
1061                def readable(self):
1062                    if isinstance(self.socket, ssl.SSLSocket):
1063                        while self.socket.pending() > 0:
1064                            self.handle_read_event()
1065                    return True
1066
1067                def _do_ssl_handshake(self):
1068                    try:
1069                        self.socket.do_handshake()
1070                    except (ssl.SSLWantReadError, ssl.SSLWantWriteError):
1071                        return
1072                    except ssl.SSLEOFError:
1073                        return self.handle_close()
1074                    except ssl.SSLError:
1075                        raise
1076                    except socket.error as err:
1077                        if err.args[0] == errno.ECONNABORTED:
1078                            return self.handle_close()
1079                    else:
1080                        self._ssl_accepting = False
1081
1082                def handle_read(self):
1083                    if self._ssl_accepting:
1084                        self._do_ssl_handshake()
1085                    else:
1086                        data = self.recv(1024)
1087                        if support.verbose:
1088                            sys.stdout.write(" server:  read %s from client\n" % repr(data))
1089                        if not data:
1090                            self.close()
1091                        else:
1092                            self.send(data.lower())
1093
1094                def handle_close(self):
1095                    self.close()
1096                    if support.verbose:
1097                        sys.stdout.write(" server:  closed connection %s\n" % self.socket)
1098
1099                def handle_error(self):
1100                    raise
1101
1102            def __init__(self, certfile):
1103                self.certfile = certfile
1104                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1105                self.port = support.bind_port(sock, '')
1106                asyncore.dispatcher.__init__(self, sock)
1107                self.listen(5)
1108
1109            def handle_accepted(self, sock_obj, addr):
1110                if support.verbose:
1111                    sys.stdout.write(" server:  new connection from %s:%s\n" %addr)
1112                self.ConnectionHandler(sock_obj, self.certfile)
1113
1114            def handle_error(self):
1115                raise
1116
1117        def __init__(self, certfile):
1118            self.flag = None
1119            self.active = False
1120            self.server = self.EchoServer(certfile)
1121            self.port = self.server.port
1122            threading.Thread.__init__(self)
1123            self.daemon = True
1124
1125        def __str__(self):
1126            return "<%s %s>" % (self.__class__.__name__, self.server)
1127
1128        def __enter__(self):
1129            self.start(threading.Event())
1130            self.flag.wait()
1131            return self
1132
1133        def __exit__(self, *args):
1134            if support.verbose:
1135                sys.stdout.write(" cleanup: stopping server.\n")
1136            self.stop()
1137            if support.verbose:
1138                sys.stdout.write(" cleanup: joining server thread.\n")
1139            self.join()
1140            if support.verbose:
1141                sys.stdout.write(" cleanup: successfully joined.\n")
1142
1143        def start (self, flag=None):
1144            self.flag = flag
1145            threading.Thread.start(self)
1146
1147        def run(self):
1148            self.active = True
1149            if self.flag:
1150                self.flag.set()
1151            while self.active:
1152                try:
1153                    asyncore.loop(1)
1154                except:
1155                    pass
1156
1157        def stop(self):
1158            self.active = False
1159            self.server.close()
1160
1161    def bad_cert_test(certfile):
1162        """
1163        Launch a server with CERT_REQUIRED, and check that trying to
1164        connect to it with the given client certificate fails.
1165        """
1166        server = ThreadedEchoServer(CERTFILE,
1167                                    certreqs=ssl.CERT_REQUIRED,
1168                                    cacerts=CERTFILE, chatty=False,
1169                                    connectionchatty=False)
1170        with server:
1171            try:
1172                with socket.socket() as sock:
1173                    s = ssl.wrap_socket(sock,
1174                                        certfile=certfile,
1175                                        ssl_version=ssl.PROTOCOL_TLSv1)
1176                    s.connect((HOST, server.port))
1177            except ssl.SSLError as x:
1178                if support.verbose:
1179                    sys.stdout.write("\nSSLError is %s\n" % x.args[1])
1180            except socket.error as x:
1181                if support.verbose:
1182                    sys.stdout.write("\nsocket.error is %s\n" % x.args[1])
1183            except IOError as x:
1184                if x.errno != errno.ENOENT:
1185                    raise
1186                if support.verbose:
1187                    sys.stdout.write("\IOError is %s\n" % str(x))
1188            else:
1189                raise AssertionError("Use of invalid cert should have failed!")
1190
1191    def server_params_test(client_context, server_context, indata=b"FOO\n",
1192                           chatty=True, connectionchatty=False):
1193        """
1194        Launch a server, connect a client to it and try various reads
1195        and writes.
1196        """
1197        server = ThreadedEchoServer(context=server_context,
1198                                    chatty=chatty,
1199                                    connectionchatty=False)
1200        with server:
1201            with client_context.wrap_socket(socket.socket()) as s:
1202                s.connect((HOST, server.port))
1203                for arg in [indata, bytearray(indata), memoryview(indata)]:
1204                    if connectionchatty:
1205                        if support.verbose:
1206                            sys.stdout.write(
1207                                " client:  sending %r...\n" % indata)
1208                    s.write(arg)
1209                    outdata = s.read()
1210                    if connectionchatty:
1211                        if support.verbose:
1212                            sys.stdout.write(" client:  read %r\n" % outdata)
1213                    if outdata != indata.lower():
1214                        raise AssertionError(
1215                            "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1216                            % (outdata[:20], len(outdata),
1217                               indata[:20].lower(), len(indata)))
1218                s.write(b"over\n")
1219                if connectionchatty:
1220                    if support.verbose:
1221                        sys.stdout.write(" client:  closing connection.\n")
1222                stats = {
1223                    'compression': s.compression(),
1224                    'cipher': s.cipher(),
1225                }
1226                s.close()
1227                return stats
1228
1229    def try_protocol_combo(server_protocol, client_protocol, expect_success,
1230                           certsreqs=None, server_options=0, client_options=0):
1231        if certsreqs is None:
1232            certsreqs = ssl.CERT_NONE
1233        certtype = {
1234            ssl.CERT_NONE: "CERT_NONE",
1235            ssl.CERT_OPTIONAL: "CERT_OPTIONAL",
1236            ssl.CERT_REQUIRED: "CERT_REQUIRED",
1237        }[certsreqs]
1238        if support.verbose:
1239            formatstr = (expect_success and " %s->%s %s\n") or " {%s->%s} %s\n"
1240            sys.stdout.write(formatstr %
1241                             (ssl.get_protocol_name(client_protocol),
1242                              ssl.get_protocol_name(server_protocol),
1243                              certtype))
1244        client_context = ssl.SSLContext(client_protocol)
1245        client_context.options = ssl.OP_ALL | client_options
1246        server_context = ssl.SSLContext(server_protocol)
1247        server_context.options = ssl.OP_ALL | server_options
1248        for ctx in (client_context, server_context):
1249            ctx.verify_mode = certsreqs
1250            # NOTE: we must enable "ALL" ciphers, otherwise an SSLv23 client
1251            # will send an SSLv3 hello (rather than SSLv2) starting from
1252            # OpenSSL 1.0.0 (see issue #8322).
1253            ctx.set_ciphers("ALL")
1254            ctx.load_cert_chain(CERTFILE)
1255            ctx.load_verify_locations(CERTFILE)
1256        try:
1257            server_params_test(client_context, server_context,
1258                               chatty=False, connectionchatty=False)
1259        # Protocol mismatch can result in either an SSLError, or a
1260        # "Connection reset by peer" error.
1261        except ssl.SSLError:
1262            if expect_success:
1263                raise
1264        except socket.error as e:
1265            if expect_success or e.errno != errno.ECONNRESET:
1266                raise
1267        else:
1268            if not expect_success:
1269                raise AssertionError(
1270                    "Client protocol %s succeeded with server protocol %s!"
1271                    % (ssl.get_protocol_name(client_protocol),
1272                       ssl.get_protocol_name(server_protocol)))
1273
1274
1275    class ThreadedTests(unittest.TestCase):
1276
1277        @skip_if_broken_ubuntu_ssl
1278        def test_echo(self):
1279            """Basic test of an SSL client connecting to a server"""
1280            if support.verbose:
1281                sys.stdout.write("\n")
1282            for protocol in PROTOCOLS:
1283                context = ssl.SSLContext(protocol)
1284                context.load_cert_chain(CERTFILE)
1285                server_params_test(context, context,
1286                                   chatty=True, connectionchatty=True)
1287
1288        def test_getpeercert(self):
1289            if support.verbose:
1290                sys.stdout.write("\n")
1291            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1292            context.verify_mode = ssl.CERT_REQUIRED
1293            context.load_verify_locations(CERTFILE)
1294            context.load_cert_chain(CERTFILE)
1295            server = ThreadedEchoServer(context=context, chatty=False)
1296            with server:
1297                s = context.wrap_socket(socket.socket())
1298                s.connect((HOST, server.port))
1299                cert = s.getpeercert()
1300                self.assertTrue(cert, "Can't get peer certificate.")
1301                cipher = s.cipher()
1302                if support.verbose:
1303                    sys.stdout.write(pprint.pformat(cert) + '\n')
1304                    sys.stdout.write("Connection cipher is " + str(cipher) + '.\n')
1305                if 'subject' not in cert:
1306                    self.fail("No subject field in certificate: %s." %
1307                              pprint.pformat(cert))
1308                if ((('organizationName', 'Python Software Foundation'),)
1309                    not in cert['subject']):
1310                    self.fail(
1311                        "Missing or invalid 'organizationName' field in certificate subject; "
1312                        "should be 'Python Software Foundation'.")
1313                self.assertIn('notBefore', cert)
1314                self.assertIn('notAfter', cert)
1315                before = ssl.cert_time_to_seconds(cert['notBefore'])
1316                after = ssl.cert_time_to_seconds(cert['notAfter'])
1317                self.assertLess(before, after)
1318                s.close()
1319
1320        def test_empty_cert(self):
1321            """Connecting with an empty cert file"""
1322            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1323                                      "nullcert.pem"))
1324        def test_malformed_cert(self):
1325            """Connecting with a badly formatted certificate (syntax error)"""
1326            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1327                                       "badcert.pem"))
1328        def test_nonexisting_cert(self):
1329            """Connecting with a non-existing cert file"""
1330            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1331                                       "wrongcert.pem"))
1332        def test_malformed_key(self):
1333            """Connecting with a badly formatted key (syntax error)"""
1334            bad_cert_test(os.path.join(os.path.dirname(__file__) or os.curdir,
1335                                       "badkey.pem"))
1336
1337        def test_rude_shutdown(self):
1338            """A brutal shutdown of an SSL server should raise an IOError
1339            in the client when attempting handshake.
1340            """
1341            listener_ready = threading.Event()
1342            listener_gone = threading.Event()
1343
1344            s = socket.socket()
1345            port = support.bind_port(s, HOST)
1346
1347            # `listener` runs in a thread.  It sits in an accept() until
1348            # the main thread connects.  Then it rudely closes the socket,
1349            # and sets Event `listener_gone` to let the main thread know
1350            # the socket is gone.
1351            def listener():
1352                s.listen(5)
1353                listener_ready.set()
1354                newsock, addr = s.accept()
1355                newsock.close()
1356                s.close()
1357                listener_gone.set()
1358
1359            def connector():
1360                listener_ready.wait()
1361                with socket.socket() as c:
1362                    c.connect((HOST, port))
1363                    listener_gone.wait()
1364                    try:
1365                        ssl_sock = ssl.wrap_socket(c)
1366                    except IOError:
1367                        pass
1368                    else:
1369                        self.fail('connecting to closed SSL socket should have failed')
1370
1371            t = threading.Thread(target=listener)
1372            t.start()
1373            try:
1374                connector()
1375            finally:
1376                t.join()
1377
1378        @skip_if_broken_ubuntu_ssl
1379        @unittest.skipUnless(hasattr(ssl, 'PROTOCOL_SSLv2'),
1380                             "OpenSSL is compiled without SSLv2 support")
1381        def test_protocol_sslv2(self):
1382            """Connecting to an SSLv2 server with various client options"""
1383            if support.verbose:
1384                sys.stdout.write("\n")
1385            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True)
1386            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_OPTIONAL)
1387            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv2, True, ssl.CERT_REQUIRED)
1388            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True)
1389            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv3, False)
1390            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_TLSv1, False)
1391            # SSLv23 client with specific SSL options
1392            if no_sslv2_implies_sslv3_hello():
1393                # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1394                try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, False,
1395                                   client_options=ssl.OP_NO_SSLv2)
1396            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1397                               client_options=ssl.OP_NO_SSLv3)
1398            try_protocol_combo(ssl.PROTOCOL_SSLv2, ssl.PROTOCOL_SSLv23, True,
1399                               client_options=ssl.OP_NO_TLSv1)
1400
1401        @skip_if_broken_ubuntu_ssl
1402        def test_protocol_sslv23(self):
1403            """Connecting to an SSLv23 server with various client options"""
1404            if support.verbose:
1405                sys.stdout.write("\n")
1406            if hasattr(ssl, 'PROTOCOL_SSLv2'):
1407                try:
1408                    try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv2, True)
1409                except (ssl.SSLError, socket.error) as x:
1410                    # this fails on some older versions of OpenSSL (0.9.7l, for instance)
1411                    if support.verbose:
1412                        sys.stdout.write(
1413                            " SSL2 client to SSL23 server test unexpectedly failed:\n %s\n"
1414                            % str(x))
1415            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True)
1416            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True)
1417            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True)
1418
1419            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1420            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_OPTIONAL)
1421            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1422
1423            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1424            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True, ssl.CERT_REQUIRED)
1425            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1426
1427            # Server with specific SSL options
1428            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv3, False,
1429                               server_options=ssl.OP_NO_SSLv3)
1430            # Will choose TLSv1
1431            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_SSLv23, True,
1432                               server_options=ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3)
1433            try_protocol_combo(ssl.PROTOCOL_SSLv23, ssl.PROTOCOL_TLSv1, False,
1434                               server_options=ssl.OP_NO_TLSv1)
1435
1436
1437        @skip_if_broken_ubuntu_ssl
1438        def test_protocol_sslv3(self):
1439            """Connecting to an SSLv3 server with various client options"""
1440            if support.verbose:
1441                sys.stdout.write("\n")
1442            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True)
1443            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_OPTIONAL)
1444            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv3, True, ssl.CERT_REQUIRED)
1445            if hasattr(ssl, 'PROTOCOL_SSLv2'):
1446                try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv2, False)
1447            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, False,
1448                               client_options=ssl.OP_NO_SSLv3)
1449            try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_TLSv1, False)
1450            if no_sslv2_implies_sslv3_hello():
1451                # No SSLv2 => client will use an SSLv3 hello on recent OpenSSLs
1452                try_protocol_combo(ssl.PROTOCOL_SSLv3, ssl.PROTOCOL_SSLv23, True,
1453                                   client_options=ssl.OP_NO_SSLv2)
1454
1455        @skip_if_broken_ubuntu_ssl
1456        def test_protocol_tlsv1(self):
1457            """Connecting to a TLSv1 server with various client options"""
1458            if support.verbose:
1459                sys.stdout.write("\n")
1460            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True)
1461            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_OPTIONAL)
1462            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_TLSv1, True, ssl.CERT_REQUIRED)
1463            if hasattr(ssl, 'PROTOCOL_SSLv2'):
1464                try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv2, False)
1465            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv3, False)
1466            try_protocol_combo(ssl.PROTOCOL_TLSv1, ssl.PROTOCOL_SSLv23, False,
1467                               client_options=ssl.OP_NO_TLSv1)
1468
1469        def test_starttls(self):
1470            """Switching from clear text to encrypted and back again."""
1471            msgs = (b"msg 1", b"MSG 2", b"STARTTLS", b"MSG 3", b"msg 4", b"ENDTLS", b"msg 5", b"msg 6")
1472
1473            server = ThreadedEchoServer(CERTFILE,
1474                                        ssl_version=ssl.PROTOCOL_TLSv1,
1475                                        starttls_server=True,
1476                                        chatty=True,
1477                                        connectionchatty=True)
1478            wrapped = False
1479            with server:
1480                s = socket.socket()
1481                s.setblocking(1)
1482                s.connect((HOST, server.port))
1483                if support.verbose:
1484                    sys.stdout.write("\n")
1485                for indata in msgs:
1486                    if support.verbose:
1487                        sys.stdout.write(
1488                            " client:  sending %r...\n" % indata)
1489                    if wrapped:
1490                        conn.write(indata)
1491                        outdata = conn.read()
1492                    else:
1493                        s.send(indata)
1494                        outdata = s.recv(1024)
1495                    msg = outdata.strip().lower()
1496                    if indata == b"STARTTLS" and msg.startswith(b"ok"):
1497                        # STARTTLS ok, switch to secure mode
1498                        if support.verbose:
1499                            sys.stdout.write(
1500                                " client:  read %r from server, starting TLS...\n"
1501                                % msg)
1502                        conn = ssl.wrap_socket(s, ssl_version=ssl.PROTOCOL_TLSv1)
1503                        wrapped = True
1504                    elif indata == b"ENDTLS" and msg.startswith(b"ok"):
1505                        # ENDTLS ok, switch back to clear text
1506                        if support.verbose:
1507                            sys.stdout.write(
1508                                " client:  read %r from server, ending TLS...\n"
1509                                % msg)
1510                        s = conn.unwrap()
1511                        wrapped = False
1512                    else:
1513                        if support.verbose:
1514                            sys.stdout.write(
1515                                " client:  read %r from server\n" % msg)
1516                if support.verbose:
1517                    sys.stdout.write(" client:  closing connection.\n")
1518                if wrapped:
1519                    conn.write(b"over\n")
1520                else:
1521                    s.send(b"over\n")
1522                if wrapped:
1523                    conn.close()
1524                else:
1525                    s.close()
1526
1527        def test_socketserver(self):
1528            """Using a SocketServer to create and manage SSL connections."""
1529            server = make_https_server(self, CERTFILE)
1530            # try to connect
1531            if support.verbose:
1532                sys.stdout.write('\n')
1533            with open(CERTFILE, 'rb') as f:
1534                d1 = f.read()
1535            d2 = ''
1536            # now fetch the same data from the HTTPS server
1537            url = 'https://%s:%d/%s' % (
1538                HOST, server.port, os.path.split(CERTFILE)[1])
1539            f = urllib.request.urlopen(url)
1540            try:
1541                dlen = f.info().get("content-length")
1542                if dlen and (int(dlen) > 0):
1543                    d2 = f.read(int(dlen))
1544                    if support.verbose:
1545                        sys.stdout.write(
1546                            " client: read %d bytes from remote server '%s'\n"
1547                            % (len(d2), server))
1548            finally:
1549                f.close()
1550            self.assertEqual(d1, d2)
1551
1552        def test_asyncore_server(self):
1553            """Check the example asyncore integration."""
1554            indata = "TEST MESSAGE of mixed case\n"
1555
1556            if support.verbose:
1557                sys.stdout.write("\n")
1558
1559            indata = b"FOO\n"
1560            server = AsyncoreEchoServer(CERTFILE)
1561            with server:
1562                s = ssl.wrap_socket(socket.socket())
1563                s.connect(('127.0.0.1', server.port))
1564                if support.verbose:
1565                    sys.stdout.write(
1566                        " client:  sending %r...\n" % indata)
1567                s.write(indata)
1568                outdata = s.read()
1569                if support.verbose:
1570                    sys.stdout.write(" client:  read %r\n" % outdata)
1571                if outdata != indata.lower():
1572                    self.fail(
1573                        "bad data <<%r>> (%d) received; expected <<%r>> (%d)\n"
1574                        % (outdata[:20], len(outdata),
1575                           indata[:20].lower(), len(indata)))
1576                s.write(b"over\n")
1577                if support.verbose:
1578                    sys.stdout.write(" client:  closing connection.\n")
1579                s.close()
1580                if support.verbose:
1581                    sys.stdout.write(" client:  connection closed.\n")
1582
1583        def test_recv_send(self):
1584            """Test recv(), send() and friends."""
1585            if support.verbose:
1586                sys.stdout.write("\n")
1587
1588            server = ThreadedEchoServer(CERTFILE,
1589                                        certreqs=ssl.CERT_NONE,
1590                                        ssl_version=ssl.PROTOCOL_TLSv1,
1591                                        cacerts=CERTFILE,
1592                                        chatty=True,
1593                                        connectionchatty=False)
1594            with server:
1595                s = ssl.wrap_socket(socket.socket(),
1596                                    server_side=False,
1597                                    certfile=CERTFILE,
1598                                    ca_certs=CERTFILE,
1599                                    cert_reqs=ssl.CERT_NONE,
1600                                    ssl_version=ssl.PROTOCOL_TLSv1)
1601                s.connect((HOST, server.port))
1602                # helper methods for standardising recv* method signatures
1603                def _recv_into():
1604                    b = bytearray(b"\0"*100)
1605                    count = s.recv_into(b)
1606                    return b[:count]
1607
1608                def _recvfrom_into():
1609                    b = bytearray(b"\0"*100)
1610                    count, addr = s.recvfrom_into(b)
1611                    return b[:count]
1612
1613                # (name, method, whether to expect success, *args)
1614                send_methods = [
1615                    ('send', s.send, True, []),
1616                    ('sendto', s.sendto, False, ["some.address"]),
1617                    ('sendall', s.sendall, True, []),
1618                ]
1619                recv_methods = [
1620                    ('recv', s.recv, True, []),
1621                    ('recvfrom', s.recvfrom, False, ["some.address"]),
1622                    ('recv_into', _recv_into, True, []),
1623                    ('recvfrom_into', _recvfrom_into, False, []),
1624                ]
1625                data_prefix = "PREFIX_"
1626
1627                for meth_name, send_meth, expect_success, args in send_methods:
1628                    indata = (data_prefix + meth_name).encode('ascii')
1629                    try:
1630                        send_meth(indata, *args)
1631                        outdata = s.read()
1632                        if outdata != indata.lower():
1633                            self.fail(
1634                                "While sending with <<{name:s}>> bad data "
1635                                "<<{outdata:r}>> ({nout:d}) received; "
1636                                "expected <<{indata:r}>> ({nin:d})\n".format(
1637                                    name=meth_name, outdata=outdata[:20],
1638                                    nout=len(outdata),
1639                                    indata=indata[:20], nin=len(indata)
1640                                )
1641                            )
1642                    except ValueError as e:
1643                        if expect_success:
1644                            self.fail(
1645                                "Failed to send with method <<{name:s}>>; "
1646                                "expected to succeed.\n".format(name=meth_name)
1647                            )
1648                        if not str(e).startswith(meth_name):
1649                            self.fail(
1650                                "Method <<{name:s}>> failed with unexpected "
1651                                "exception message: {exp:s}\n".format(
1652                                    name=meth_name, exp=e
1653                                )
1654                            )
1655
1656                for meth_name, recv_meth, expect_success, args in recv_methods:
1657                    indata = (data_prefix + meth_name).encode('ascii')
1658                    try:
1659                        s.send(indata)
1660                        outdata = recv_meth(*args)
1661                        if outdata != indata.lower():
1662                            self.fail(
1663                                "While receiving with <<{name:s}>> bad data "
1664                                "<<{outdata:r}>> ({nout:d}) received; "
1665                                "expected <<{indata:r}>> ({nin:d})\n".format(
1666                                    name=meth_name, outdata=outdata[:20],
1667                                    nout=len(outdata),
1668                                    indata=indata[:20], nin=len(indata)
1669                                )
1670                            )
1671                    except ValueError as e:
1672                        if expect_success:
1673                            self.fail(
1674                                "Failed to receive with method <<{name:s}>>; "
1675                                "expected to succeed.\n".format(name=meth_name)
1676                            )
1677                        if not str(e).startswith(meth_name):
1678                            self.fail(
1679                                "Method <<{name:s}>> failed with unexpected "
1680                                "exception message: {exp:s}\n".format(
1681                                    name=meth_name, exp=e
1682                                )
1683                            )
1684                        # consume data
1685                        s.read()
1686
1687                # Make sure sendmsg et al are disallowed to avoid
1688                # inadvertent disclosure of data and/or corruption
1689                # of the encrypted data stream
1690                self.assertRaises(NotImplementedError, s.sendmsg, [b"data"])
1691                self.assertRaises(NotImplementedError, s.recvmsg, 100)
1692                self.assertRaises(NotImplementedError,
1693                                  s.recvmsg_into, bytearray(100))
1694
1695                s.write(b"over\n")
1696                s.close()
1697
1698        def test_handshake_timeout(self):
1699            # Issue #5103: SSL handshake must respect the socket timeout
1700            server = socket.socket(socket.AF_INET)
1701            host = "127.0.0.1"
1702            port = support.bind_port(server)
1703            started = threading.Event()
1704            finish = False
1705
1706            def serve():
1707                server.listen(5)
1708                started.set()
1709                conns = []
1710                while not finish:
1711                    r, w, e = select.select([server], [], [], 0.1)
1712                    if server in r:
1713                        # Let the socket hang around rather than having
1714                        # it closed by garbage collection.
1715                        conns.append(server.accept()[0])
1716                for sock in conns:
1717                    sock.close()
1718
1719            t = threading.Thread(target=serve)
1720            t.start()
1721            started.wait()
1722
1723            try:
1724                try:
1725                    c = socket.socket(socket.AF_INET)
1726                    c.settimeout(0.2)
1727                    c.connect((host, port))
1728                    # Will attempt handshake and time out
1729                    self.assertRaisesRegex(socket.timeout, "timed out",
1730                                           ssl.wrap_socket, c)
1731                finally:
1732                    c.close()
1733                try:
1734                    c = socket.socket(socket.AF_INET)
1735                    c = ssl.wrap_socket(c)
1736                    c.settimeout(0.2)
1737                    # Will attempt handshake and time out
1738                    self.assertRaisesRegex(socket.timeout, "timed out",
1739                                           c.connect, (host, port))
1740                finally:
1741                    c.close()
1742            finally:
1743                finish = True
1744                t.join()
1745                server.close()
1746
1747        def test_default_ciphers(self):
1748            context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
1749            try:
1750                # Force a set of weak ciphers on our client context
1751                context.set_ciphers("DES")
1752            except ssl.SSLError:
1753                self.skipTest("no DES cipher available")
1754            with ThreadedEchoServer(CERTFILE,
1755                                    ssl_version=ssl.PROTOCOL_SSLv23,
1756                                    chatty=False) as server:
1757                with socket.socket() as sock:
1758                    s = context.wrap_socket(sock)
1759                    with self.assertRaises((OSError, ssl.SSLError)):
1760                        s.connect((HOST, server.port))
1761            self.assertIn("no shared cipher", str(server.conn_errors[0]))
1762
1763        @unittest.skipUnless("tls-unique" in ssl.CHANNEL_BINDING_TYPES,
1764                             "'tls-unique' channel binding not available")
1765        def test_tls_unique_channel_binding(self):
1766            """Test tls-unique channel binding."""
1767            if support.verbose:
1768                sys.stdout.write("\n")
1769
1770            server = ThreadedEchoServer(CERTFILE,
1771                                        certreqs=ssl.CERT_NONE,
1772                                        ssl_version=ssl.PROTOCOL_TLSv1,
1773                                        cacerts=CERTFILE,
1774                                        chatty=True,
1775                                        connectionchatty=False)
1776            with server:
1777                s = ssl.wrap_socket(socket.socket(),
1778                                    server_side=False,
1779                                    certfile=CERTFILE,
1780                                    ca_certs=CERTFILE,
1781                                    cert_reqs=ssl.CERT_NONE,
1782                                    ssl_version=ssl.PROTOCOL_TLSv1)
1783                s.connect((HOST, server.port))
1784                # get the data
1785                cb_data = s.get_channel_binding("tls-unique")
1786                if support.verbose:
1787                    sys.stdout.write(" got channel binding data: {0!r}\n"
1788                                     .format(cb_data))
1789
1790                # check if it is sane
1791                self.assertIsNotNone(cb_data)
1792                self.assertEqual(len(cb_data), 12) # True for TLSv1
1793
1794                # and compare with the peers version
1795                s.write(b"CB tls-unique\n")
1796                peer_data_repr = s.read().strip()
1797                self.assertEqual(peer_data_repr,
1798                                 repr(cb_data).encode("us-ascii"))
1799                s.close()
1800
1801                # now, again
1802                s = ssl.wrap_socket(socket.socket(),
1803                                    server_side=False,
1804                                    certfile=CERTFILE,
1805                                    ca_certs=CERTFILE,
1806                                    cert_reqs=ssl.CERT_NONE,
1807                                    ssl_version=ssl.PROTOCOL_TLSv1)
1808                s.connect((HOST, server.port))
1809                new_cb_data = s.get_channel_binding("tls-unique")
1810                if support.verbose:
1811                    sys.stdout.write(" got another channel binding data: {0!r}\n"
1812                                     .format(new_cb_data))
1813                # is it really unique
1814                self.assertNotEqual(cb_data, new_cb_data)
1815                self.assertIsNotNone(cb_data)
1816                self.assertEqual(len(cb_data), 12) # True for TLSv1
1817                s.write(b"CB tls-unique\n")
1818                peer_data_repr = s.read().strip()
1819                self.assertEqual(peer_data_repr,
1820                                 repr(new_cb_data).encode("us-ascii"))
1821                s.close()
1822
1823        def test_compression(self):
1824            context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1825            context.load_cert_chain(CERTFILE)
1826            stats = server_params_test(context, context,
1827                                       chatty=True, connectionchatty=True)
1828            if support.verbose:
1829                sys.stdout.write(" got compression: {!r}\n".format(stats['compression']))
1830            self.assertIn(stats['compression'], { None, 'ZLIB', 'RLE' })
1831
1832        @unittest.skipUnless(hasattr(ssl, 'OP_NO_COMPRESSION'),
1833                             "ssl.OP_NO_COMPRESSION needed for this test")
1834        def test_compression_disabled(self):
1835            context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1836            context.load_cert_chain(CERTFILE)
1837            context.options |= ssl.OP_NO_COMPRESSION
1838            stats = server_params_test(context, context,
1839                                       chatty=True, connectionchatty=True)
1840            self.assertIs(stats['compression'], None)
1841
1842        def test_dh_params(self):
1843            # Check we can get a connection with ephemeral Diffie-Hellman
1844            context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
1845            context.load_cert_chain(CERTFILE)
1846            context.load_dh_params(DHFILE)
1847            context.set_ciphers("kEDH")
1848            stats = server_params_test(context, context,
1849                                       chatty=True, connectionchatty=True)
1850            cipher = stats["cipher"][0]
1851            parts = cipher.split("-")
1852            if "ADH" not in parts and "EDH" not in parts and "DHE" not in parts:
1853                self.fail("Non-DH cipher: " + cipher[0])
1854
1855
1856def test_main(verbose=False):
1857    if support.verbose:
1858        plats = {
1859            'Linux': platform.linux_distribution,
1860            'Mac': platform.mac_ver,
1861            'Windows': platform.win32_ver,
1862        }
1863        for name, func in plats.items():
1864            plat = func()
1865            if plat and plat[0]:
1866                plat = '%s %r' % (name, plat)
1867                break
1868        else:
1869            plat = repr(platform.platform())
1870        print("test_ssl: testing with %r %r" %
1871            (ssl.OPENSSL_VERSION, ssl.OPENSSL_VERSION_INFO))
1872        print("          under %s" % plat)
1873        print("          HAS_SNI = %r" % ssl.HAS_SNI)
1874
1875    for filename in [
1876        CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, BYTES_CERTFILE,
1877        ONLYCERT, ONLYKEY, BYTES_ONLYCERT, BYTES_ONLYKEY,
1878        BADCERT, BADKEY, EMPTYCERT]:
1879        if not os.path.exists(filename):
1880            raise support.TestFailed("Can't read certificate file %r" % filename)
1881
1882    tests = [ContextTests, BasicSocketTests]
1883
1884    if support.is_resource_enabled('network'):
1885        tests.append(NetworkedTests)
1886
1887    if _have_threads:
1888        thread_info = support.threading_setup()
1889        if thread_info and support.is_resource_enabled('network'):
1890            tests.append(ThreadedTests)
1891
1892    try:
1893        support.run_unittest(*tests)
1894    finally:
1895        if _have_threads:
1896            support.threading_cleanup(*thread_info)
1897
1898if __name__ == "__main__":
1899    test_main()