Skip to content

onyums 0.5.0 — pure-Rust crypto: no C compiled for TLS or certificates

Latest

Choose a tag to compare

@physics515 physics515 released this 24 Sep 13:08
· 5 commits to master since this release
d4aca04

The crypto stack is pure Rust. No C is compiled or linked for TLS or for certificates — closing the project's oldest locked principle, "100% Rust, no FFI, ever".

What changed

ring was the last C library onyums controlled, and it had two jobs. Both are now pure Rust:

Job Was Now
TLS (every relay handshake) ring rustls-graviola — by rustls' own author
Self-signed onion certificate ring, via rcgen's crypto feature a p256 signer

graviola is genuinely C-free: zero .c/.S files, no build.rs, no cc build-dependency, no links key, zero runtime dependencies. Its assembly is Rust core::arch::asm! — a language feature, not a C binding.

rcgen's crypto feature turned out not to be required at all: its SigningKey/PublicKeyData traits sit outside that feature, so onyums supplies its own signer and rcgen keeps only pem.

$ cargo tree --workspace --all-features --target all -i ring
warning: nothing to print.

ring still appears in Cargo.lock — rustls-webpki declares it optionally, and a lockfile records possible rather than resolved dependencies. Present in the lock is not compiled, and deny.toml now says so beside a ban with no wrapper.

Two C libraries remain in the tree, both arti's and neither reachable from onyums' manifest: libsqlite3-sys (directory cache) and liblzma-sys (directory compression).

⚠️ Breaking: x86_64 and aarch64 only

graviola is a compile_error! on any other architecture. onyums 0.4.x built wherever ring did — 0.5.0 does not. If you need armv7, riscv64 or a 32-bit target, pin onyums = "0.4".

CI cannot catch this for you: all four checked target triples are x86_64 or aarch64.

Nothing in the public API signature moved — OnionTorClient is still TorClient<TokioRustlsRuntime>.

Verified live

live tier: ready_timeout(60s) = true, status = Reachable
live tier: fetch attempt 8 served the app body
test result: ok. 1 passed; 0 failed — 576.47s

The service published, reached Reachable in 36 seconds, and a second Tor client fetched the application's body through a real rendezvous circuit — with no C crypto in the binary. Bootstrap, which is many TLS handshakes to directory caches, took 28s against the previous release's 3 minutes.

Honest caveat: the fetch needed 8 attempts where 0.4.0's run needed 1. That is HsDir descriptor propagation on the client side — broken or slow crypto yields handshake errors, not timeouts that then succeed, and the service was Reachable throughout — but it is one run each and no performance comparison is claimed from it.

Also in this release

  • Dedicated tests for the two encodings that fail silently at build time and loudly at handshake time: the public key must be an X9.62 uncompressed point (not an SPKI, which rcgen would nest inside another), and the signature must be ASN.1 DER (not the 64-byte fixed-width r || s, which embeds silently and every verifier rejects).
  • Certificates now carry a random 16-byte serial with the top bit cleared — RFC 5280 wants a positive serial and CA/B Forum wants ≥64 bits of entropy. rcgen only minted one under its crypto feature, so this was required, not cosmetic.

Verification

Stable 1.98, --workspace --all-features: build green · 249 lib tests + 502 onyums-skin + 11 doctests, 0 failed · clippy -D warnings clean (no #[allow] added) · rustdoc -D warnings clean · rustfmt clean · cargo-deny green on both graphs with -D unused-wrapper -D advisory-not-detected. All 7 CI checks green on the merge commit.

A correction worth passing on

The roadmap had named rustls-rustcrypto as the pure-Rust provider option. It fails a maintenance check outright: only release 0.0.2-alpha from 2024-04-24, with two of three published versions yanked. rustls-graviola passes easily. The first crate that comes to mind for "is there a pure-Rust X" may be the abandoned one — check release dates and yank status before adopting or dismissing the category.