Jean-Paul Calderone | c7b3c89 | 2011-03-02 19:40:02 -0500 | [diff] [blame^] | 1 | # Copyright (C) Jean-Paul Calderone |
| 2 | # See LICENSE for details. |
Jean-Paul Calderone | 5ef8651 | 2008-04-26 19:06:28 -0400 | [diff] [blame] | 3 | # |
| 4 | # Stress tester for thread-related bugs in global_info_callback in |
| 5 | # src/ssl/context.c. In 0.7 and earlier, this will somewhat reliably |
| 6 | # segfault or abort after a few dozen to a few thousand iterations on an SMP |
| 7 | # machine (generally not on a UP machine) due to uses of Python/C API |
| 8 | # without holding the GIL. |
| 9 | |
| 10 | from itertools import count |
| 11 | from threading import Thread |
| 12 | from socket import socket |
| 13 | |
| 14 | from OpenSSL.SSL import Context, TLSv1_METHOD, Connection, WantReadError |
| 15 | from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey |
| 16 | |
| 17 | cleartextPrivateKeyPEM = ( |
| 18 | "-----BEGIN RSA PRIVATE KEY-----\n" |
| 19 | "MIICXAIBAAKBgQDaemNe1syksAbFFpF3aoOrZ18vB/IQNZrAjFqXPv9iieJm7+Tc\n" |
| 20 | "g+lA/v0qmoEKrpT2xfwxXmvZwBNM4ZhyRC3DPIFEyJV7/3IA1p5iuMY/GJI1VIgn\n" |
| 21 | "aikQCnrsyxtaRpsMBeZRniaVzcUJ+XnEdFGEjlo+k0xlwfVclDEMwgpXAQIDAQAB\n" |
| 22 | "AoGBALi0a7pMQqqgnriVAdpBVJveQtxSDVWi2/gZMKVZfzNheuSnv4amhtaKPKJ+\n" |
| 23 | "CMZtHkcazsE2IFvxRN/kgato9H3gJqq8nq2CkdpdLNVKBoxiCtkLfutdY4SQLtoY\n" |
| 24 | "USN7exk131pchsAJXYlR6mCW+ZP+E523cNwpPgsyKxVbmXSBAkEA9470fy2W0jFM\n" |
| 25 | "taZFslpntKSzbvn6JmdtjtvWrM1bBaeeqFiGBuQFYg46VaCUaeRWYw02jmYAsDYh\n" |
| 26 | "ZQavmXThaQJBAOHtlAQ0IJJEiMZr6vtVPH32fmbthSv1AUSYPzKqdlQrUnOXPQXu\n" |
| 27 | "z70cFoLG1TvPF5rBxbOkbQ/s8/ka5ZjPfdkCQCeC7YsO36+UpsWnUCBzRXITh4AC\n" |
| 28 | "7eYLQ/U1KUJTVF/GrQ/5cQrQgftwgecAxi9Qfmk4xqhbp2h4e0QAmS5I9WECQH02\n" |
| 29 | "0QwrX8nxFeTytr8pFGezj4a4KVCdb2B3CL+p3f70K7RIo9d/7b6frJI6ZL/LHQf2\n" |
| 30 | "UP4pKRDkgKsVDx7MELECQGm072/Z7vmb03h/uE95IYJOgY4nfmYs0QKA9Is18wUz\n" |
| 31 | "DpjfE33p0Ha6GO1VZRIQoqE24F8o5oimy3BEjryFuw4=\n" |
| 32 | "-----END RSA PRIVATE KEY-----\n") |
| 33 | |
| 34 | |
| 35 | cleartextCertificatePEM = ( |
| 36 | "-----BEGIN CERTIFICATE-----\n" |
| 37 | "MIICfTCCAeYCAQEwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAlVTMRkwFwYD\n" |
| 38 | "VQQDExBweW9wZW5zc2wuc2YubmV0MREwDwYDVQQHEwhOZXcgWW9yazESMBAGA1UE\n" |
| 39 | "ChMJUHlPcGVuU1NMMREwDwYDVQQIEwhOZXcgWW9yazEQMA4GCSqGSIb3DQEJARYB\n" |
| 40 | "IDEQMA4GA1UECxMHVGVzdGluZzAeFw0wODAzMjUxOTA0MTNaFw0wOTAzMjUxOTA0\n" |
| 41 | "MTNaMIGGMQswCQYDVQQGEwJVUzEZMBcGA1UEAxMQcHlvcGVuc3NsLnNmLm5ldDER\n" |
| 42 | "MA8GA1UEBxMITmV3IFlvcmsxEjAQBgNVBAoTCVB5T3BlblNTTDERMA8GA1UECBMI\n" |
| 43 | "TmV3IFlvcmsxEDAOBgkqhkiG9w0BCQEWASAxEDAOBgNVBAsTB1Rlc3RpbmcwgZ8w\n" |
| 44 | "DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSwBsUWkXdqg6tnXy8H8hA1\n" |
| 45 | "msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nAE0zhmHJELcM8gUTIlXv/\n" |
| 46 | "cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXNxQn5ecR0UYSOWj6TTGXB\n" |
| 47 | "9VyUMQzCClcBAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAmm0Vzvv1O91WLl2LnF2P\n" |
| 48 | "q55LJdOnJbCCXIgxLdoVmvYAz1ZJq1eGKgKWI5QLgxiSzJLEU7KK//aVfiZzoCd5\n" |
| 49 | "RipBiEEMEV4eAY317bHPwPP+4Bj9t0l8AsDLseC5vLRHgxrLEu3bn08DYx6imB5Q\n" |
| 50 | "UBj849/xpszEM7BhwKE0GiQ=\n" |
| 51 | "-----END CERTIFICATE-----\n") |
| 52 | |
| 53 | count = count() |
| 54 | def go(): |
| 55 | port = socket() |
| 56 | port.bind(('', 0)) |
| 57 | port.listen(1) |
| 58 | |
| 59 | called = [] |
| 60 | def info(conn, where, ret): |
| 61 | print count.next() |
| 62 | called.append(None) |
| 63 | context = Context(TLSv1_METHOD) |
| 64 | context.set_info_callback(info) |
| 65 | context.use_certificate( |
| 66 | load_certificate(FILETYPE_PEM, cleartextCertificatePEM)) |
| 67 | context.use_privatekey( |
| 68 | load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM)) |
| 69 | |
| 70 | while 1: |
| 71 | client = socket() |
| 72 | client.setblocking(False) |
| 73 | client.connect_ex(port.getsockname()) |
| 74 | |
| 75 | clientSSL = Connection(Context(TLSv1_METHOD), client) |
| 76 | clientSSL.set_connect_state() |
| 77 | |
| 78 | server, ignored = port.accept() |
| 79 | server.setblocking(False) |
| 80 | |
| 81 | serverSSL = Connection(context, server) |
| 82 | serverSSL.set_accept_state() |
| 83 | |
| 84 | del called[:] |
| 85 | while not called: |
| 86 | for ssl in clientSSL, serverSSL: |
| 87 | try: |
| 88 | ssl.do_handshake() |
| 89 | except WantReadError: |
| 90 | pass |
| 91 | |
| 92 | |
| 93 | threads = [Thread(target=go, args=()) for i in xrange(2)] |
| 94 | for th in threads: |
| 95 | th.start() |
| 96 | for th in threads: |
| 97 | th.join() |