Source code for toolbox.asyncio.streams

import asyncio
import ssl
from typing import Optional


[docs] async def tls_handshake( reader: asyncio.StreamReader, writer: asyncio.StreamWriter, ssl_context: Optional[ssl.SSLContext] = None, server_side: bool = False, ): """ Manually perform a TLS handshake over a stream. Args: reader: The reader of the client connection. writer: The writer of the client connection. ssl_context: The SSL context to use. Defaults to None. server_side: Whether the connection is server-side or not. Defaults to False. Note: If the `ssl_context` is not passed and `server_side` is not set, then `ssl.create_default_context()` will be used. For Python 3.6 to 3.9 you can use `ssl.PROTOCOL_TLS` for the SSL context. For Python 3.10+ you need to either use `ssl.PROTOCOL_TLS_CLIENT` or `ssl.PROTOCOL_TLS_SERVER` depending on the role of the reader/writer. Example: Client code: .. code-block:: python from toolbox.asyncio.streams import tls_handshake import asyncio async def client(): reader, writer = await asyncio.open_connection("httpbin.org", 443, ssl=False) await tls_handshake(reader=reader, writer=writer) # Communication is now encrypted. ... asyncio.run(client()) Server code: .. code-block:: python from toolbox.asyncio.streams import tls_handshake import asyncio import ssl async def server(reader, writer): context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) context.load_cert_chain(certfile="server.crt", keyfile="server.key") await tls_handshake( reader=reader, writer=writer, ssl_context=context, server_side=True, ) # Connection is now encrypted. ... async def main(): srv = await asyncio.start_server(server, host="127.0.0.1", port=8888) async with srv: await srv.serve_forever() asyncio.run(main()) """ if not server_side and not ssl_context: ssl_context = ssl.create_default_context() transport = writer.transport protocol = transport.get_protocol() loop = asyncio.get_event_loop() new_transport = await loop.start_tls( transport=transport, protocol=protocol, sslcontext=ssl_context, server_side=server_side, ) reader._transport = new_transport writer._transport = new_transport