#!./python import ssl import socket import threading from test.test_ssl import SIGNED_CERTFILE, SIGNING_CA from http.server import HTTPServer as _HTTPServer from http.server import BaseHTTPRequestHandler from http.client import HTTPSConnection PROTO_MAP = { "SSLv23": ssl.PROTOCOL_SSLv23, "SSLv3": ssl.PROTOCOL_SSLv3, "TLSv1": ssl.PROTOCOL_TLSv1, "TLSv1_1": ssl.PROTOCOL_TLSv1_1, "TLSv1_2": ssl.PROTOCOL_TLSv1_2, } class HTTPSServer(_HTTPServer): def __init__(self, server_address, handler_class, context): _HTTPServer.__init__(self, server_address, handler_class) self.context = context def get_request(self): sock, addr = self.socket.accept() sslconn = self.context.wrap_socket(sock, server_side=True) return sslconn, addr class RequestHandler(BaseHTTPRequestHandler): def do_GET(self): body = b"OK" self.send_response(200) self.send_header("Content-Type", "text/plain; charset=utf-8") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def log_message(self, *args): pass class HTTPSServerThread(threading.Thread): handler_class = RequestHandler def __init__(self, context, host="localhost"): self.flag = None self.server = HTTPSServer((host, 0), self.handler_class, context) self.port = self.server.server_port self.host = host threading.Thread.__init__(self) self.daemon = True def start(self, flag=None): self.flag = flag threading.Thread.start(self) def run(self): if self.flag: self.flag.set() try: self.server.serve_forever(0.05) finally: self.server.server_close() def stop(self): self.server.shutdown() def make_server(proto): context = ssl.SSLContext(proto) context.load_cert_chain(SIGNED_CERTFILE) server = HTTPSServerThread(context) flag = threading.Event() server.start(flag) flag.wait() return server def client_context(proto): context = ssl.SSLContext(proto) context.load_verify_locations(SIGNING_CA) context.verify_mode = ssl.CERT_REQUIRED return context def attempt_connect(server, context): try: conn = HTTPSConnection(server.host, server.port, context=context) conn.request("GET", "/") response = conn.getresponse().read() except ssl.SSLError: return False else: return response == b"OK" def connection_test(): servers = {} client = {} for name, proto in PROTO_MAP.items(): servers[name] = make_server(proto) client[name] = client_context(proto) results = [] try: for spn, server in servers.items(): for cpn, context in client.items(): success = attempt_connect(server, context) results.append((spn, cpn, success)) finally: for server in servers.values(): server.stop() return results def print_results(results): fmt = "{:<10} {:<10} {}" print(fmt.format("server", "client", "can connect")) print(fmt.format("="*9, "="*9, "="*11)) for spn, cpn, success in sorted(results): print(fmt.format(spn, cpn, success)) if __name__ == "__main__": results = connection_test() print_results(results)