Skip to content

onyums 0.4.0 — arti 0.46, rustls instead of OpenSSL, and the first verified live serve

Choose a tag to compare

@physics515 physics515 released this 24 Sep 03:58
· 9 commits to master since this release

The embedded Tor client moves two arti minors and off OpenSSL onto rustls, two security advisories close, and the live onion-service path is verified against the real Tor network for the first time.

Since 0.3.1 (2026-06-18) the published crate has lagged the repository by a wide margin — 0.3.1 predates onyums-skin entirely. This release closes that gap.

Security

0.3.1's dependency graph fails cargo deny check advisories today. This release closes:

Advisory Crate Fixed in
RUSTSEC-2026-0258 h2 — unbounded empty DATA frames 0.4.19
RUSTSEC-2026-0285 rustls — TLS 1.3 handshake messages accepted across encryption-level boundaries 0.23.45
yanked chacha20 0.10.1 0.10.2
RUSTSEC-2025-0052 async-std discontinued left the tree

arti 0.44 → 0.46, and rustls instead of OpenSSL

arti-client and every tor-* crate move to 0.46.0 (Arti 2.6.0). Notably, 2.5.1 fixed arti reading XON data rates as bits/s rather than bytes/s — sending 8× less data than allowed, squarely on the onion-service path.

The TLS runtime under arti is now rustls rather than native-tls, which removes openssl-sys from the dependency graph: 50 crates and 611 lines leave Cargo.lock, and the binary carries one TLS implementation instead of two.

This is not an FFI-free TLS stack, and the roadmap does not claim it is. rustls' ring provider vendors C and assembly from BoringSSL, so building onyums still needs a C toolchain. The swap replaced one C crypto library with another; what it bought is OpenSSL's removal, an advisory retired, and a single TLS stack. The remaining C dependencies are enumerated and wrapper-pinned in deny.toml.

onyums now installs rustls' crypto provider as the process default before building any TLS configuration, and defers to one your application installed first.

Live verification — a first for this project

Onion service name: xfywsfgmwjvrs3pivzamhjyfxwh6pzhzcgkknpzazhqhqhnygam7u6qd.onion
live tier: fetch attempt 1 served the app body
test result: ok. 1 passed; 0 failed — 257.16s

arti bootstrapped a full directory over rustls, the service published its descriptor, a second Tor client dialled the .onion through a real rendezvous circuit and received the application's body, and shutdown returned cleanly.

Scope of that claim: one host, one run, by hand. CI does not run this tier, so the README's feature-status row stays amber — "verified once", not "continuously verified".

The --ignored live tier itself was also repaired: it could previously hang indefinitely past its own timeouts (observed at 70 minutes against a ~21-minute budget). It now runs on an explicit runtime with bounded teardown under a wall-clock watchdog that aborts and names the stuck phase. On its first real outing it failed loudly in 360s on a cold directory cache instead of hanging — the redesign working as intended.

Fixes

  • A peer-provokable memory leak in the accept loop. A rendezvous circuit whose accept() failed was never passed to CircuitPolicy::forget, leaking one per-circuit accounting entry per failed handshake, for the service's lifetime. A peer provokes one by abandoning the handshake at zero cost. (The existing test had pinned the bug by asserting the leak was expected.)
  • Two public metrics helpers that misreported under load. circuits_failed_transport() counted host-global capacity refusals as arti transport failures — telling an operator "your Tor transport is failing" when the truth was "you are full". total_streams() omitted capacity-refused streams, so a service serving 1 and refusing 99 computed a 100% served fraction.
  • A rustls panic reachable from two public constructors. ProvidedCert::from_pem and the default self-signed acceptor built a ServerConfig before any crypto provider was installed — a panic, not an error, for any downstream app whose graph enables a second rustls provider.

Other

  • cargo-deny now denies advisory-not-detected, so an ignore entry whose crate has left the tree fails CI instead of lingering as a decoration — the advisories-side twin of the unused-wrapper guard.
  • New troubleshooting entry for arti's fs-mistrust rejecting a world-writable ancestor of the storage directory, which names neither the path nor the remedy on its own.

Breaking changes

  • MSRV is 1.91 (from 1.85 at 0.3.1), set by the arti stack.
  • OnionTorClient is now TorClient<TokioRustlsRuntime>, was TorClient<TokioNativeTlsRuntime>. Code written against the OnionTorClient alias is unaffected — that is what the alias exists for. Code that spelled the native-tls runtime out will not compile.

Not in this release

onyums-skin is still unpublished on crates.io, so this tag is a GitHub release only; onyums cannot be published to the registry until skin goes first. The full picture of what is verified, what is only offline-tested, and what is blocked upstream lives in README.md and ROADMAP.md.