async def main(): # It might be desirable to move these out of the examples # directory, as this test are now relying on them being around file_path = join(dirname(dirname(__file__)), 'examples') cert_file = join(file_path, 'ssl_test.crt') key_file = join(file_path, 'ssl_test_rsa') server_context = curiossl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_context.load_cert_chain(certfile=cert_file, keyfile=key_file) stdlib_client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) curio_client_context = curiossl.create_default_context(ssl.Purpose.SERVER_AUTH) try: os.remove('/tmp/curionet') except OSError: pass server_task = await spawn(partial(network.unix_server, '/tmp/curionet', handler, ssl=server_context)) await sleep(0.1) for test_context in (curio_client_context, stdlib_client_context): test_context.check_hostname = False test_context.verify_mode = ssl.CERT_NONE resp = await client('/tmp/curionet', test_context) assert resp == b'Back atcha: Hello, world!' await server_task.cancel()
def uri_compile(uri, is_server): url = urllib.parse.urlparse(uri) kw = {} if url.scheme == 'tunneludp': if not url.fragment: raise argparse.ArgumentTypeError( 'destitation must be assign in tunnel udp mode, ' 'example tunneludp://:53#8.8.8.8:53') host, _, port = url.fragment.partition(':') kw['target_addr'] = (host, int(port)) if url.scheme in ('https', ): if not url.fragment: raise argparse.ArgumentTypeError('#keyfile,certfile is needed') keyfile, _, certfile = url.fragment.partition(',') ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) kw['ssl_context'] = ssl_context proto = server_protos[url.scheme] if is_server else \ client_protos[url.scheme] cipher, _, loc = url.netloc.rpartition('@') if cipher: cipher_cls, _, password = cipher.partition(':') if url.scheme.startswith('ss'): kw['cipher_cls'] = ciphers[cipher_cls] kw['password'] = password.encode() elif url.scheme in ('http', 'https', 'socks'): kw['auth'] = (cipher_cls.encode(), password.encode()) else: pass if loc: kw['host'], _, port = loc.partition(':') kw['port'] = int(port) if port else 1080 return types.SimpleNamespace(proto=proto, scheme=url.scheme, kw=kw)
async def main(): # It might be desirable to move these out of the examples # directory, as this test are now relying on them being around file_path = join(dirname(dirname(__file__)), 'examples') cert_file = join(file_path, 'ssl_test.crt') key_file = join(file_path, 'ssl_test_rsa') server_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_context.load_cert_chain(certfile=cert_file, keyfile=key_file) stdlib_client_context = ssl.create_default_context( ssl.Purpose.SERVER_AUTH) curio_client_context = curiossl.create_default_context( ssl.Purpose.SERVER_AUTH) server_coro = server('localhost', 10000, server_context) server_task = await spawn(server_coro) for test_context in (curio_client_context, stdlib_client_context): test_context.check_hostname = False test_context.verify_mode = ssl.CERT_NONE resp = await client('localhost', 10000, test_context) assert resp == b'Back atcha: Hello, world!' await server_task.cancel()
def uri_compile(uri, is_server): url = urllib.parse.urlparse(uri) kw = {} if url.scheme == "tunneludp": if not url.fragment: raise argparse.ArgumentTypeError( "destitation must be assign in tunnel udp mode, " "example tunneludp://:53#8.8.8.8:53") host, _, port = url.fragment.partition(":") kw["target_addr"] = (host, int(port)) if url.scheme in ("https", ): if not url.fragment: raise argparse.ArgumentTypeError("#keyfile,certfile is needed") keyfile, _, certfile = url.fragment.partition(",") ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) kw["ssl_context"] = ssl_context proto = server_protos[url.scheme] if is_server else client_protos[ url.scheme] cipher, _, loc = url.netloc.rpartition("@") if cipher: cipher_cls, _, password = cipher.partition(":") if url.scheme.startswith("ss"): kw["cipher_cls"] = ciphers[cipher_cls] kw["password"] = password.encode() elif url.scheme in ("http", "https", "socks"): kw["auth"] = (cipher_cls.encode(), password.encode()) else: pass if loc: kw["host"], _, port = loc.partition(":") kw["port"] = int(port) if port else 1080 return types.SimpleNamespace(proto=proto, scheme=url.scheme, kw=kw)
def create_listening_ssl_socket(address, certfile, keyfile): """ Create and return a listening TLS socket on a given address. """ # check if 2 files exist. If not, raise exceptions if os.path.isfile(certfile) and os.path.isfile(keyfile): ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.options |= ( ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION ) ssl_context.set_ciphers("ECDHE+AESGCM") ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) ssl_context.set_alpn_protocols(["h2"]) sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) csock = ssl_context.wrap_socket(sock) while True: try: csock.send(None) except StopIteration as e: sock = e.value sock.bind(address) sock.listen() return sock else: raise FileNotFoundError(certfile + " and/or " + keyfile + " don't exist. HTTP/2 needs certificate files.")
def get_ssl(url): ssl_context = None if url.scheme in ("https", ): if not url.fragment: raise argparse.ArgumentTypeError("#keyfile,certfile is needed") keyfile, _, certfile = url.fragment.partition(",") ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) return ssl_context
async def main(host, port): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE sock = await network.open_connection(host, port, ssl=True, server_hostname=None) for i in range(1000): msg = ("Message %d" % i).encode("ascii") print(msg) await sock.sendall(msg) resp = await sock.recv(1000) assert msg == resp await sock.close()
def create_ssl_context(self): """ Create an SSL context that has reasonable settings and supports alpn for h2 and http/1.1 in that order. """ ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.options |= ssl.OP_NO_TLSv1 ssl_context.options |= ssl.OP_NO_TLSv1_1 ssl_context.options |= ssl.OP_NO_COMPRESSION ssl_context.set_ciphers(self.tls_ciphers) ssl_context.load_cert_chain(certfile=self.certfile, keyfile=self.keyfile) ssl_context.set_alpn_protocols(["h2", "http/1.1"]) return ssl_context
async def main(): # It might be desirable to move these out of the examples # directory, as this test are now relying on them being around file_path = join(dirname(dirname(__file__)), 'examples') cert_file = join(file_path, 'ssl_test.crt') key_file = join(file_path, 'ssl_test_rsa') server_context = curiossl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_context.load_cert_chain(certfile=cert_file, keyfile=key_file) stdlib_client_context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH) curio_client_context = curiossl.create_default_context(ssl.Purpose.SERVER_AUTH) server_task = await spawn(partial(network.tcp_server, '', 10000, handler, ssl=server_context)) await sleep(0.1) for test_context in (curio_client_context, stdlib_client_context): test_context.check_hostname = False test_context.verify_mode = ssl.CERT_NONE resp = await client('localhost', 10000, test_context) assert resp == b'Back atcha: Hello, world!' await server_task.cancel()
async def main(host, port): ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE sock = await network.open_connection(host, port, ssl=True, server_hostname=None) for i in range(1000): msg = ('Message %d' % i).encode('ascii') print(msg) await sock.sendall(msg) resp = await sock.recv(1000) assert msg == resp await sock.close()
def create_listening_ssl_socket(address): """ Create and return a listening TLS socket on a given address. """ ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.options |= (ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION) ssl_context.set_ciphers("ECDHE+AESGCM") ssl_context.load_cert_chain(certfile="cert.crt", keyfile="cert.key") ssl_context.set_alpn_protocols(["h2"]) sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock = ssl_context.wrap_socket(sock) sock.bind(address) sock.listen() return sock
def create_listening_ssl_socket(address, certfile, keyfile): """ Create and return a listening TLS socket on a given address. """ ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.options |= ( ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION ) ssl_context.set_ciphers("ECDHE+AESGCM") ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) ssl_context.set_alpn_protocols(["h2"]) sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock = ssl_context.wrap_socket(sock) sock.bind(address) sock.listen() return sock
async def make_request(proxy: AsyncProxy, url: str, resolve_host=False, timeout=None): url = URL(url) dest_host = url.host if resolve_host: resolver = Resolver() _, dest_host = await resolver.resolve(url.host) sock: curio.io.Socket = await proxy.connect(dest_host=dest_host, dest_port=url.port, timeout=timeout) ssl_context: Optional[curiossl.CurioSSLContext] = None if url.scheme == 'https': ssl_context = curiossl.create_default_context() if ssl_context is not None: sock = await ssl_context.wrap_socket(sock, do_handshake_on_connect=False, server_hostname=url.host) await sock.do_handshake() stream = sock.as_stream() request = ('GET {rel_url} HTTP/1.1\r\n' 'Host: {host}\r\n' 'Connection: close\r\n\r\n') request = request.format(rel_url=url.path_qs, host=url.host) request = request.encode('ascii') await stream.write(request) response = await stream.read(1024) status_line = response.split(b'\r\n', 1)[0] status_line = status_line.decode('utf-8', 'surrogateescape') version, status_code, *reason = status_line.split() return int(status_code)
def get_ssl_params(self, url, verify, cert): if url.scheme != 'https' or (not verify and not cert): return {'ssl_context': None} ssl_params = {} ssl_context = ssl.create_default_context() if verify: if isinstance(verify, str): if not exists(verify): raise FileNotFoundError( f'Could not find a suitable TLS CA certificate bundle, ' f'invalid path: {verify}') if isdir(verify): ssl_context.load_verify_locations(capath=verify) else: ssl_context.load_verify_locations(cafile=verify) ssl_params['server_hostname'] = url.raw_host ssl_context.verify_mode = ssl.CERT_REQUIRED if cert: if isinstance(cert, str): cert_file = cert key_file = None else: cert_file, key_file = cert if cert_file and not exists(cert_file): raise FileNotFoundError( f'Could not find the TLS certificate file, ' f'invalid path: {cert_file}') if key_file and not exists(key_file): raise FileNotFoundError( f'Could not find the TLS certificate file, ' f'invalid path: {key_file}') ssl_context.load_cert_chain(cert_file, key_file) ssl_params['ssl_context'] = ssl_context return ssl_params
def create_listening_ssl_socket(address, certfile, keyfile): if os.path.isfile(certfile) and os.path.isfile(keyfile): ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.options |= (ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1 | ssl.OP_NO_COMPRESSION) ssl_context.set_ciphers("ECDHE+AESGCM") ssl_context.load_cert_chain(certfile=certfile, keyfile=keyfile) ssl_context.set_alpn_protocols(["h2"]) sock = socket.socket() sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) csock = ssl_context.wrap_socket(sock) while True: try: csock.send(None) except StopIteration as e: sock = e.value sock.bind(address) sock.listen() return sock else: raise FileNotFoundError(certfile + " and/or " + keyfile + " 找不到证书文件, HTTP2为了安全, 必须使用加密证书.")
# curiosslecho.py # # Use sslclient.py to test import curio from curio import ssl from curio import network from socket import * KEYFILE = "ssl_test_rsa" # Private key CERTFILE = "ssl_test.crt" # Certificate (self-signed) async def handle(client, addr): print('Connection from', addr) client.setsockopt(IPPROTO_TCP, TCP_NODELAY, 1) async with client: while True: data = await client.recv(100000) if not data: break await client.sendall(data) print('Connection closed') if __name__ == '__main__': ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile=CERTFILE, keyfile=KEYFILE) curio.run(network.tcp_server('', 25000, handle, ssl=ssl_context))
KEYFILE = os.path.dirname(__file__) + "/ssl_test_rsa" # Private key CERTFILE = os.path.dirname( __file__) + "/ssl_test.crt" # Certificate (self-signed) async def handler(client, addr): s = client.as_stream() async for line in s: line = line.strip() if not line: break print(line) await s.write(b'''HTTP/1.0 200 OK\r Content-type: text/plain\r \r If you're seeing this, it probably worked. Yay! ''') await s.write(time.asctime().encode('ascii')) await client.close() if __name__ == '__main__': ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ssl_context.load_cert_chain(certfile=CERTFILE, keyfile=KEYFILE) print('Connect to https://localhost:10000 to see if it works') try: curio.run(curio.tcp_server('', 10000, handler, ssl=ssl_context)) except KeyboardInterrupt: pass