C API for rustls::quic (client side), for QUIC stacks such as ngtcp2 (curl HTTP/3)

オープン
#705 コメント 5 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
35/100
issue の種類
機能追加
明瞭さ
おおむね明確
活発さ
活発
技術スタック
rust
領域
api, security

調査の方向性

Review the proposed implementation on the quic branch of the reporter’s fork, especially librustls/src/quic.rs and the regenerated rustls.h, then compare its conventions with the README and CONTRIBUTING.md. The issue leaves API shape and traffic-secret handling open for maintainer input. A completed contribution should settle those choices and include the agreed client-side QUIC API with tests and documentation.

索引モデルが issue の本文から書いたものです。

説明

I would like to add a C API over rustls::quic (client side), so that QUIC stacks written in C can use Rustls for the TLS part of the handshake. A working implementation with tests is on the branch quic of my fork, one commit on top of main: https://github.com/marie-222/rustls-ffi/tree/quic (librustls/src/quic.rs and the regenerated rustls.h). cargo fmt --check, cargo clippy, cargo test and cargo check --no-default-features --features ring pass. I have not opened a PR, following CONTRIBUTING.md.

Why

curl builds its HTTP/3 on ngtcp2, whose TLS backends are OpenSSL (3.5+ / quictls / BoringSSL), GnuTLS and wolfSSL; there is no Rustls one. So curl --with-rustls cannot do HTTP/3, and Encrypted Client Hello, which curl only has through Rustls (OpenSSL 3.5 has no ECH API), cannot be combined with HTTP/3.

With this API and a small ngtcp2 crypto helper (HKDF/AEAD/header protection from OpenSSL's libcrypto, TLS from rustls-ffi), I have curl 8.23.0 doing HTTP/3, and ECH over HTTP/3, against public servers (cloudflare.com, www.google.com), and against a test server that sends a Retry and updates its keys during a 6 MiB download. The curl patch and the helper are in https://github.com/small-gear-lab/apt-packaging (the helper is derived from ngtcp2's quictls one; I may offer it to ngtcp2 separately).

The API

All on one new object, rustls_quic_connection, following the conventions of the README:

rustls_quic_client_connection_new(config, quic_version, server_name, alpn..., params..., &conn)
rustls_quic_connection_read_hs(conn, data, len)           // bytes of CRYPTO frames received
rustls_quic_connection_write_hs(conn, out, cap, &len, &keys)  // bytes to send; which keys are available after them
rustls_quic_connection_is_handshaking / _get_alert / _free
rustls_quic_connection_get_negotiated_ciphersuite
rustls_quic_connection_get_peer_transport_parameters
rustls_quic_connection_get_peer_certificate               // then rustls_certificate_get_der
rustls_quic_connection_get_secret(conn, kind, out, cap, &len)

Questions

  1. Traffic secrets. rustls::quic returns finished key objects and does not expose the secrets, but ngtcp2 (and other stacks) derive their own packet keys from secrets (ngtcp2_crypto_derive_and_install_rx/tx_key). I take them from the key log: the connection works on a copy of the ClientConfig whose key_log keeps this connection's secrets and forwards every line to the config's own key log. It works, and I checked (with a test) that a secret is available from the moment the handshake bytes that give it have been read, which is before write_hs reports that level's keys. But it relies on the key log. Would you rather expose the secrets (or the raw material of quic::Keys) from rustls::quic, or is the key log route acceptable for the C API?
  2. Shape. I used a new object rather than extending rustls_connection, because rustls::quic::ClientConnection is a different type. Is that what you would want? Naming (rustls_quic_*) and the "NOT_FOUND vs NULL" choices follow the README as I read it; I will change them to whatever you prefer.
  3. Scope. Client side only for now, no 0-RTT or session resumption (a client ticket cannot be serialized with the public API of rustls, so I may ask about that separately in the rustls repository).

I am happy to adapt the API, add tests or documentation, or split it, before a PR.

主要言語
Rust
スター
171
フォーク
46
平均マージ
15時間 49分
マージ済み PR(30日)
19

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

rustls/rustls-ffi のほかの issue

rustls/rustls-ffi の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。