Skip to main content

Monkey-patch for qh3 to support mutual TLS (client certificate authentication)

Project description

qh3_mutual_tls_patch

Runtime monkey-patch that adds mutual TLS (client certificate authentication) support to qh3's server-side TLS 1.3 implementation.

Problem

qh3's TLS 1.3 server does not send a CertificateRequest message during the handshake, so the client never presents its certificate. This makes it impossible to use mutual TLS authentication in QUIC servers built with qh3.

Solution

This package patches qh3's Context class at runtime to:

  1. Inject a CertificateRequest message into the server handshake (after EncryptedExtensions, before Certificate)
  2. Handle the client's Certificate, CertificateVerify, and Finished messages
  3. Verify the client's certificate signature using Ed25519

The patch is non-destructive: connections with verify_mode = ssl.CERT_NONE are unaffected.

Installation

pip install qh3_mutual_tls_patch

Or install from source:

pip install .

Usage

Call apply() once before creating any QUIC connections:

import ssl
from qh3_mutual_tls_patch import apply
from qh3.quic.configuration import QuicConfiguration

# Apply the patch (safe to call multiple times)
apply()

# Now you can request client certificates on the server side
config = QuicConfiguration(is_client=False)
config.verify_mode = ssl.CERT_OPTIONAL  # or ssl.CERT_REQUIRED
# ... set certificate, private_key, alpn_protocols, etc.

After the handshake, the client's certificate is available via context.get_peercert().

How it works

The patch hooks three internal qh3 functions:

  • push_encrypted_extensions — sets a flag after EncryptedExtensions is written
  • push_message — intercepts the next push_message call (for the server Certificate) to inject CertificateRequest with its own transcript hash scope beforehand
  • _server_handle_hello — wraps the original to restore the key-schedule hash after qh3's Finished-anticipation step, then transitions to custom states

Two custom TLS states (SERVER_EXPECT_CLIENT_CERT and SERVER_EXPECT_CLIENT_CERT_VERIFY) handle the client's response before handing control back to qh3's SERVER_EXPECT_FINISHED state.

Compatibility

  • qh3 >= 1.2.1
  • Python >= 3.10

Limitations

  • Only Ed25519 is advertised in the CertificateRequest signature algorithms extension.
  • The patch relies on qh3 internals and may break with future qh3 releases.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

qh3_mutual_tls_patch-0.1.0.tar.gz (3.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qh3_mutual_tls_patch-0.1.0-py3-none-any.whl (3.4 kB view details)

Uploaded Python 3

File details

Details for the file qh3_mutual_tls_patch-0.1.0.tar.gz.

File metadata

  • Download URL: qh3_mutual_tls_patch-0.1.0.tar.gz
  • Upload date:
  • Size: 3.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for qh3_mutual_tls_patch-0.1.0.tar.gz
Algorithm Hash digest
SHA256 55109c35fa06bce062ff89390f03e6d7af663d5f25cfc42f71aef773c6403d26
MD5 cbb70bcae1fd24551cd4a3a185c18cc0
BLAKE2b-256 760fff41a85327a4b40add1d46833e53dab466f474029d5b5287b1867b7aea7e

See more details on using hashes here.

File details

Details for the file qh3_mutual_tls_patch-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for qh3_mutual_tls_patch-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4721f884cf28d76f852b4c3106709e844cea180294c5f2495e8755c297be4959
MD5 9244cab187ced4ede48206d3c7b3bd75
BLAKE2b-256 12a20e3ef0f254a388d11d9594846856770a5bc3b374223e5817d07e2625a889

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page