# server_ssl.py import asyncio import ssl from aioquic.asyncio import serve from aioquic.asyncio.protocol import QuicConnectionProtocol from aioquic.h3.connection import H3Connection from aioquic.h3.events import HeadersReceived from aioquic.quic.configuration import QuicConfiguration from aioquic.quic.events import ProtocolNegotiated class HttpServerProtocol(QuicConnectionProtocol): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._http = None def quic_event_received(self, event): if isinstance(event, ProtocolNegotiated) and event.alpn_protocol == "h3": self._http = H3Connection(self._quic) if self._http: for http_event in self._http.handle_event(event): if isinstance(http_event, HeadersReceived): self._http.send_headers(http_event.stream_id, [(b":status", b"200")]) self._http.send_data(http_event.stream_id, b"Hello QUIC!", end_stream=True) self.transmit() def create_ssl_context(): """Erstellt einen SSL-Context mit allen QUIC-Cipher-Suites""" context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) context.minimum_version = ssl.TLSVersion.TLSv1_3 # QUIC benötigt TLS 1.3 context.load_cert_chain("cert.pem", "key.pem") # Cipher-Suites für TLS 1.3 (wird von OpenSSL automatisch gesetzt) # TLS 1.3 verwendet: AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305, AES-128-CCM # context.set_ciphers("TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384:TLS13-CHACHA20-POLY1305-SHA256:TLS13-AES-128-CCM-SHA256") context.set_ciphers("TLS13-AES-128-GCM-SHA256:TLS13-AES-256-GCM-SHA384") return context async def main(): config = QuicConfiguration(is_client=False, alpn_protocols=["h3"]) config.load_cert_chain("cert.pem", "key.pem") # Zusätzlich explizit TLS 1.3 erzwingen config.verify_mode = ssl.CERT_NONE print("Starting HTTP/3 server on localhost:4433...") print("Enforcing TLS 1.3 with all QUIC cipher suites") server = await serve("localhost", 4433, configuration=config, create_protocol=HttpServerProtocol) print("Server running. Test with: curl --http3 https://localhost:4433/ -k") try: await asyncio.Future() except KeyboardInterrupt: server.close() await server.wait_closed() if __name__ == "__main__": asyncio.run(main())