98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
# Copyright (C) Jean-Paul Calderone
|
|
# See LICENSE for details.
|
|
#
|
|
# Stress tester for thread-related bugs in global_info_callback in
|
|
# src/ssl/context.c. In 0.7 and earlier, this will somewhat reliably
|
|
# segfault or abort after a few dozen to a few thousand iterations on an SMP
|
|
# machine (generally not on a UP machine) due to uses of Python/C API
|
|
# without holding the GIL.
|
|
|
|
from itertools import count
|
|
from threading import Thread
|
|
from socket import socket
|
|
|
|
from OpenSSL.SSL import Context, TLSv1_METHOD, Connection, WantReadError
|
|
from OpenSSL.crypto import FILETYPE_PEM, load_certificate, load_privatekey
|
|
|
|
cleartextPrivateKeyPEM = (
|
|
"-----BEGIN RSA PRIVATE KEY-----\n"
|
|
"MIICXAIBAAKBgQDaemNe1syksAbFFpF3aoOrZ18vB/IQNZrAjFqXPv9iieJm7+Tc\n"
|
|
"g+lA/v0qmoEKrpT2xfwxXmvZwBNM4ZhyRC3DPIFEyJV7/3IA1p5iuMY/GJI1VIgn\n"
|
|
"aikQCnrsyxtaRpsMBeZRniaVzcUJ+XnEdFGEjlo+k0xlwfVclDEMwgpXAQIDAQAB\n"
|
|
"AoGBALi0a7pMQqqgnriVAdpBVJveQtxSDVWi2/gZMKVZfzNheuSnv4amhtaKPKJ+\n"
|
|
"CMZtHkcazsE2IFvxRN/kgato9H3gJqq8nq2CkdpdLNVKBoxiCtkLfutdY4SQLtoY\n"
|
|
"USN7exk131pchsAJXYlR6mCW+ZP+E523cNwpPgsyKxVbmXSBAkEA9470fy2W0jFM\n"
|
|
"taZFslpntKSzbvn6JmdtjtvWrM1bBaeeqFiGBuQFYg46VaCUaeRWYw02jmYAsDYh\n"
|
|
"ZQavmXThaQJBAOHtlAQ0IJJEiMZr6vtVPH32fmbthSv1AUSYPzKqdlQrUnOXPQXu\n"
|
|
"z70cFoLG1TvPF5rBxbOkbQ/s8/ka5ZjPfdkCQCeC7YsO36+UpsWnUCBzRXITh4AC\n"
|
|
"7eYLQ/U1KUJTVF/GrQ/5cQrQgftwgecAxi9Qfmk4xqhbp2h4e0QAmS5I9WECQH02\n"
|
|
"0QwrX8nxFeTytr8pFGezj4a4KVCdb2B3CL+p3f70K7RIo9d/7b6frJI6ZL/LHQf2\n"
|
|
"UP4pKRDkgKsVDx7MELECQGm072/Z7vmb03h/uE95IYJOgY4nfmYs0QKA9Is18wUz\n"
|
|
"DpjfE33p0Ha6GO1VZRIQoqE24F8o5oimy3BEjryFuw4=\n"
|
|
"-----END RSA PRIVATE KEY-----\n")
|
|
|
|
|
|
cleartextCertificatePEM = (
|
|
"-----BEGIN CERTIFICATE-----\n"
|
|
"MIICfTCCAeYCAQEwDQYJKoZIhvcNAQEEBQAwgYYxCzAJBgNVBAYTAlVTMRkwFwYD\n"
|
|
"VQQDExBweW9wZW5zc2wuc2YubmV0MREwDwYDVQQHEwhOZXcgWW9yazESMBAGA1UE\n"
|
|
"ChMJUHlPcGVuU1NMMREwDwYDVQQIEwhOZXcgWW9yazEQMA4GCSqGSIb3DQEJARYB\n"
|
|
"IDEQMA4GA1UECxMHVGVzdGluZzAeFw0wODAzMjUxOTA0MTNaFw0wOTAzMjUxOTA0\n"
|
|
"MTNaMIGGMQswCQYDVQQGEwJVUzEZMBcGA1UEAxMQcHlvcGVuc3NsLnNmLm5ldDER\n"
|
|
"MA8GA1UEBxMITmV3IFlvcmsxEjAQBgNVBAoTCVB5T3BlblNTTDERMA8GA1UECBMI\n"
|
|
"TmV3IFlvcmsxEDAOBgkqhkiG9w0BCQEWASAxEDAOBgNVBAsTB1Rlc3RpbmcwgZ8w\n"
|
|
"DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANp6Y17WzKSwBsUWkXdqg6tnXy8H8hA1\n"
|
|
"msCMWpc+/2KJ4mbv5NyD6UD+/SqagQqulPbF/DFea9nAE0zhmHJELcM8gUTIlXv/\n"
|
|
"cgDWnmK4xj8YkjVUiCdqKRAKeuzLG1pGmwwF5lGeJpXNxQn5ecR0UYSOWj6TTGXB\n"
|
|
"9VyUMQzCClcBAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAmm0Vzvv1O91WLl2LnF2P\n"
|
|
"q55LJdOnJbCCXIgxLdoVmvYAz1ZJq1eGKgKWI5QLgxiSzJLEU7KK//aVfiZzoCd5\n"
|
|
"RipBiEEMEV4eAY317bHPwPP+4Bj9t0l8AsDLseC5vLRHgxrLEu3bn08DYx6imB5Q\n"
|
|
"UBj849/xpszEM7BhwKE0GiQ=\n"
|
|
"-----END CERTIFICATE-----\n")
|
|
|
|
count = count()
|
|
def go():
|
|
port = socket()
|
|
port.bind(('', 0))
|
|
port.listen(1)
|
|
|
|
called = []
|
|
def info(conn, where, ret):
|
|
print count.next()
|
|
called.append(None)
|
|
context = Context(TLSv1_METHOD)
|
|
context.set_info_callback(info)
|
|
context.use_certificate(
|
|
load_certificate(FILETYPE_PEM, cleartextCertificatePEM))
|
|
context.use_privatekey(
|
|
load_privatekey(FILETYPE_PEM, cleartextPrivateKeyPEM))
|
|
|
|
while 1:
|
|
client = socket()
|
|
client.setblocking(False)
|
|
client.connect_ex(port.getsockname())
|
|
|
|
clientSSL = Connection(Context(TLSv1_METHOD), client)
|
|
clientSSL.set_connect_state()
|
|
|
|
server, ignored = port.accept()
|
|
server.setblocking(False)
|
|
|
|
serverSSL = Connection(context, server)
|
|
serverSSL.set_accept_state()
|
|
|
|
del called[:]
|
|
while not called:
|
|
for ssl in clientSSL, serverSSL:
|
|
try:
|
|
ssl.do_handshake()
|
|
except WantReadError:
|
|
pass
|
|
|
|
|
|
threads = [Thread(target=go, args=()) for i in xrange(2)]
|
|
for th in threads:
|
|
th.start()
|
|
for th in threads:
|
|
th.join()
|