Skip to content

Commit

Permalink
Merge pull request #39 from jawah/release-1.1
Browse files Browse the repository at this point in the history
Release 1.1
  • Loading branch information
Ousret authored Sep 20, 2024
2 parents 7145f48 + 260369a commit f39c656
Show file tree
Hide file tree
Showing 54 changed files with 2,715 additions and 1,185 deletions.
6 changes: 6 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ repos:
args: [ --fix ]
# Run the formatter.
- id: ruff-format
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.11.0
hooks:
- id: mypy
args: [--check-untyped-defs]
exclude: 'tests/|examples/|docs/'
30 changes: 30 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
1.1.0 (2024-09-20)
====================

**Added**
- Support for Post-Quantum KX Kyber768 (NIST Round 3) with X25519.
- Backport "QUIC Version 2".
"Rework packet encoding to support different protocol versions" https://github.com/aiortc/aioquic/commit/bd3497cce9aa906c47d5b7216752f55beed3d9d3
"Add encryption for QUIC v2" https://github.com/aiortc/aioquic/commit/abf51897bb67f459921e4c26c8b3ea445aa79832
"Refactor retry / version negotiation handling" https://github.com/aiortc/aioquic/commit/70dd040893d7d8af5a2a92361c1e844ebf867abb
"Add support for version_information transport parameter" https://github.com/aiortc/aioquic/commit/a59d9ad0b1df423376bf8b30ebb7642861fef54e
"Check Chosen Version matches the version in use by the connection" https://github.com/aiortc/aioquic/commit/a59d9ad0b1df423376bf8b30ebb7642861fef54e

**Changed**
- Insert GREASE in KX, TLS Version and Ciphers.
- Backport "Only buffer up to 512 KiB of pending CRYPTO frames" https://github.com/aiortc/aioquic/commit/174a2ebbe928686ef9663acc663b3ac06c2d56f2
- Backport "Improved path challenge handling" https://github.com/aiortc/aioquic/commit/b507364ea51f3e654decd143cc99f7001b5b7923
- Backport "Limit the number of pending connection IDs marked for retirement." https://github.com/aiortc/aioquic/commit/4f73f18a23c22f48ef43cb3629b0686757f096af
- Backport "During address validation, count the entire received datagram" https://github.com/aiortc/aioquic/commit/afe5525822f71e277e534b08f198ec8724a7ad59
- Update aws-lc-rs v1.8.1 to v1.9.0
- Default supported signature algorithms to: ``ECDSA_SECP256R1_SHA256, RSA_PSS_RSAE_SHA256, RSA_PKCS1_SHA256, ECDSA_SECP384R1_SHA384, RSA_PSS_RSAE_SHA384, RSA_PKCS1_SHA384, RSA_PSS_RSAE_SHA512, RSA_PKCS1_SHA512, ED25519``.

**Fixed**
- Certificate fingerprint matching.
- Backport upstream urllib3/urllib3#3434: util/ssl: make code (certificate fingerprint matching) resilient to missing hash functions.
In certain environments such as in a FIPS enabled system, certain algorithms such as md5 may be unavailable.

**Misc**
- Backport "Use is for type comparisons" https://github.com/aiortc/aioquic/commit/5c55e0c75d414ab171a09a732c2d8aaf6f178c05
- Postpone annotations parsing with ``from __future__ import annotations`` everywhere in order to simplify type annotations.

1.0.9 (2024-08-17)
====================

Expand Down
10 changes: 5 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "qh3"
version = "1.0.9"
version = "1.1.0"
edition = "2021"
rust-version = "1.75"
license = "BSD-3"
Expand All @@ -25,7 +25,7 @@ chacha20poly1305 = "0.10.1"
pkcs8 = { version = "0.10.2", features = ["encryption", "pem"] }
pkcs1 = { version = "0.7.5", features = ["pem"] }
rustls-pemfile = "2.1.2"
aws-lc-rs = { version = "1.8.1", features=["bindgen"], default-features = false }
aws-lc-rs = { version = "1.9.0", features=["bindgen", "unstable"], default-features = false }
x509-ocsp = { version = "0.2.1", features = ["builder"] }
x509-cert = "0.2.5"
der = "0.7.9"
Expand Down
19 changes: 10 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,33 +1,34 @@
qh3
===

|pypi-pyversions|

.. |pypi-v| image:: https://img.shields.io/pypi/v/qh3.svg
:target: https://pypi.python.org/pypi/qh3
|pypi-pyversions| |pypi-stats|

.. |pypi-pyversions| image:: https://img.shields.io/pypi/pyversions/qh3.svg
:target: https://pypi.python.org/pypi/qh3
:alt: Supported Interpreters

.. |pypi-stats| image:: https://img.shields.io/pypi/dm/qh3
:target: https://pypistats.org/packages/qh3
:alt: PyPI - Downloads

What is ``qh3``?
----------------

``qh3`` is a maintained fork of the ``aioquic`` library.

It is lighter, and a bit faster, and more adapted to a broader audience as this package has no external dependency
It is lighter, faster, and more adapted to a broader audience as this package has no external dependency
and does not rely on mainstream OpenSSL.

While it is a compatible fork, it is not a drop-in replacement since the first major. See the CHANGELOG for details.

Regularly improved and expect a better time to initial response in issues and PRs.

``qh3`` is a library for the QUIC network protocol in Python. It features
a minimal TLS 1.3 implementation, a QUIC stack, and an HTTP/3 stack.

QUIC was standardized in `RFC 9000`_ and HTTP/3 in `RFC 9114`_.
``qh3`` follow the standardized version of QUIC and HTTP/3.

QUIC stack conforming with `RFC 9000`_ (QUIC v1) and `RFC 9369`_ (QUIC v2)

To learn more about ``qh3`` please `read the documentation`_.

``qh3`` stands for **Q** UIC . **H** TTP/ **3**.
Expand Down Expand Up @@ -65,6 +66,7 @@ Features
- logging TLS traffic secrets
- logging QUIC events in QLOG format
- HTTP/3 server push support
- Post-Quantum (KEM) Key-Exchange (Kyber R3 NIST)

Requirements
------------
Expand All @@ -84,11 +86,10 @@ License
``qh3`` is released under the `BSD license`_.

.. _read the documentation: https://qh3.readthedocs.io/en/latest/
.. _QUIC implementations: https://github.com/quicwg/base-drafts/wiki/Implementations
.. _cryptography: https://cryptography.io/
.. _BSD license: https://qh3.readthedocs.io/en/latest/license.html
.. _RFC 8446: https://datatracker.ietf.org/doc/html/rfc8446
.. _RFC 9000: https://datatracker.ietf.org/doc/html/rfc9000
.. _RFC 9114: https://datatracker.ietf.org/doc/html/rfc9114
.. _RFC 9369: https://datatracker.ietf.org/doc/html/rfc9369
.. _niquests: https://github.com/jawah/niquests
.. _urllib3.future: https://github.com/jawah/urllib3.future
1 change: 1 addition & 0 deletions examples/demo.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#
# demo application for http3_server.py
#
from __future__ import annotations

import datetime
import os
Expand Down
6 changes: 4 additions & 2 deletions examples/doq_client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from __future__ import annotations

import argparse
import asyncio
import logging
import pickle
import ssl
import struct
from typing import Optional, cast
from typing import cast

from dnslib.dns import QTYPE, DNSHeader, DNSQuestion, DNSRecord

Expand All @@ -20,7 +22,7 @@
class DnsClientProtocol(QuicConnectionProtocol):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._ack_waiter: Optional[asyncio.Future[DNSRecord]] = None
self._ack_waiter: asyncio.Future[DNSRecord] | None = None

async def query(self, query_name: str, query_type: str) -> None:
# serialize query
Expand Down
7 changes: 4 additions & 3 deletions examples/doq_server.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import annotations

import argparse
import asyncio
import logging
import struct
from typing import Dict, Optional

from dnslib.dns import DNSRecord

Expand Down Expand Up @@ -34,12 +35,12 @@ class SessionTicketStore:
"""

def __init__(self) -> None:
self.tickets: Dict[bytes, SessionTicket] = {}
self.tickets: dict[bytes, SessionTicket] = {}

def add(self, ticket: SessionTicket) -> None:
self.tickets[ticket.ticket] = ticket

def pop(self, label: bytes) -> Optional[SessionTicket]:
def pop(self, label: bytes) -> SessionTicket | None:
return self.tickets.pop(label, None)


Expand Down
36 changes: 19 additions & 17 deletions examples/http3_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import argparse
import asyncio
import logging
Expand All @@ -6,7 +8,7 @@
import ssl
import time
from collections import deque
from typing import BinaryIO, Callable, Deque, Dict, List, Optional, cast
from typing import BinaryIO, Callable, Deque, cast
from urllib.parse import urlparse

import wsproto
Expand Down Expand Up @@ -44,7 +46,7 @@ def __init__(
method: str,
url: URL,
content: bytes = b"",
headers: Optional[Dict] = None,
headers: dict | None = None,
) -> None:
if headers is None:
headers = {}
Expand All @@ -62,7 +64,7 @@ def __init__(
self.http = http
self.queue: asyncio.Queue[str] = asyncio.Queue()
self.stream_id = stream_id
self.subprotocol: Optional[str] = None
self.subprotocol: str | None = None
self.transmit = transmit
self.websocket = wsproto.Connection(wsproto.ConnectionType.CLIENT)

Expand Down Expand Up @@ -112,14 +114,14 @@ class HttpClient(QuicConnectionProtocol):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)

self.pushes: Dict[int, Deque[H3Event]] = {}
self._http: Optional[H3Connection] = None
self._request_events: Dict[int, Deque[H3Event]] = {}
self._request_waiter: Dict[int, asyncio.Future[Deque[H3Event]]] = {}
self._websockets: Dict[int, WebSocket] = {}
self.pushes: dict[int, Deque[H3Event]] = {}
self._http: H3Connection | None = None
self._request_events: dict[int, Deque[H3Event]] = {}
self._request_waiter: dict[int, asyncio.Future[Deque[H3Event]]] = {}
self._websockets: dict[int, WebSocket] = {}
self._http = H3Connection(self._quic)

async def get(self, url: str, headers: Optional[Dict] = None) -> Deque[H3Event]:
async def get(self, url: str, headers: dict | None = None) -> Deque[H3Event]:
"""
Perform a GET request.
"""
Expand All @@ -128,7 +130,7 @@ async def get(self, url: str, headers: Optional[Dict] = None) -> Deque[H3Event]:
)

async def post(
self, url: str, data: bytes, headers: Optional[Dict] = None
self, url: str, data: bytes, headers: dict | None = None
) -> Deque[H3Event]:
"""
Perform a POST request.
Expand All @@ -138,7 +140,7 @@ async def post(
)

async def websocket(
self, url: str, subprotocols: Optional[List[str]] = None
self, url: str, subprotocols: list[str] | None = None
) -> WebSocket:
"""
Open a WebSocket.
Expand Down Expand Up @@ -229,9 +231,9 @@ async def _request(self, request: HttpRequest) -> Deque[H3Event]:
async def perform_http_request(
client: HttpClient,
url: str,
data: Optional[str],
data: str | None,
include: bool,
output_dir: Optional[str],
output_dir: str | None,
) -> None:
# perform request
start = time.time()
Expand Down Expand Up @@ -278,7 +280,7 @@ async def perform_http_request(
def process_http_pushes(
client: HttpClient,
include: bool,
output_dir: Optional[str],
output_dir: str | None,
) -> None:
for _, http_events in client.pushes.items():
method = ""
Expand Down Expand Up @@ -333,10 +335,10 @@ def save_session_ticket(ticket: SessionTicket) -> None:

async def main(
configuration: QuicConfiguration,
urls: List[str],
data: Optional[str],
urls: list[str],
data: str | None,
include: bool,
output_dir: Optional[str],
output_dir: str | None,
local_port: int,
zero_rtt: bool,
) -> None:
Expand Down
Loading

0 comments on commit f39c656

Please sign in to comment.