The fastest way to guarantee a CVE never reaches a downstream Cargo.lock is to remove the vulnerable dependency from the graph entirely — not patch around it, not pin a fixed version, remove it.
Today we released OxiTLS 0.2.1 — a security-hardening release for the COOLJAPAN Pure Rust TLS transport stack. It eliminates RUSTSEC-2026-0104 (a rustls-webpki CRL-parsing panic) from the dependency graph, closes a replay bypass in OCSP staple validation, and fixes a Certificate Transparency parsing bug that silently dropped every embedded SCT extension it was supposed to verify.
No OpenSSL. No native-tls. No ring. No FFI. No -sys crates on the path you actually ship. As of 0.2.1, no webpki or rustls-webpki either — the new in-workspace oxitls-rustcrypto-provider fork carries the same Pure-Rust CryptoProvider without them. Pure Rust, from the byte that hits the socket to the AEAD that protects it, compiling to a single static binary with no system libraries and no build-time C toolchain.
Why OxiTLS 0.2.1 is a game changer
Security releases are where “Pure Rust” either pays off or turns out to be marketing. 0.2.1 is a real test of the former:
- A
rustls-webpki0.102.x CRL-parsing panic (RUSTSEC-2026-0104) sat in the dependency graph behind the default Pure-Rust provider — even a codebase that never triggers the vulnerable code path still carries the advisory incargo audit, in every downstream SBOM, and in every security questionnaire that asks whether known RUSTSEC advisories exist in the tree. - OCSP staple validation scanned every
SingleResponsein a staple without binding it to the certificate actually being verified — a response with no entry for the target certificate, or only entries for a different certificate from the same issuer, could still resolve toOcspCheckResult::Good. - OCSP responses carried no freshness check tied to
thisUpdate/nextUpdate— a captured, staleGoodresponse could be replayed after the real certificate status had changed. - A Certificate Transparency SCT list embedded directly in an X.509 certificate — the form RFC 6962 §3.3 wraps in a DER
OCTET STRING— fed its wrapper bytes straight into the TLS-format parser as if they were the list’s own length prefix. Every certificate carrying a real, embedded SCT extension failed to parse, so SCT verification silently never ran on that path.
OxiTLS 0.2.1 ends all of that.
- RUSTSEC-2026-0104 is gone, not patched around. A new in-workspace crate,
oxitls-rustcrypto-provider, forksrustls-rustcrypto0.0.2-alpha with thewebpki/rustls-webpkidependency removed entirely — certificate and signature algorithm identifiers now route throughrustls-pki-types::alg_idinstead. - Zero source changes to pick it up. The workspace
Cargo.tomlrenames the dependency (rustls-rustcrypto = { package = "oxitls-rustcrypto-provider", ... }), sooxitls-adapter-rustls-rustcryptokeeps compiling against the samerustls_rustcrypto::extern name — a version bump is the whole migration. - OCSP
CertIDis now actually checked.issuerNameHash,issuerKeyHash(recomputed by a newocsp_digestcovering id-sha1 / sha256 / sha384 / sha512 per RFC 6960 §4.1.1), andserialNumbermust match the certificate under verification and its issuer before aGood/Unknownresponse is trusted — 7 new unit tests, including a dedicated id-sha1 regression pair. - Staple freshness is enforced. A matching
Good/Unknownoutside itsthisUpdate..=nextUpdatewindow is now rejected as stale, closing the replay bypass; a matchingRevokedverdict stays authoritative regardless of freshness — fail-safe by design. - Embedded SCTs parse correctly.
extract_sct_extensionnow strips the RFC 6962 DEROCTET STRINGwrapper (both short- and long-form DER lengths) before handing bytes to the TLS-format parser — 4 new unit tests confirm it. - All of it under test. 443 tests passing with
--all-features(358 with default features) across 11 workspace crates totaling 27,748 lines of Rust, zero clippy / compiler / rustdoc warnings.
Technical Deep Dive: the crypto engine, the trust stores, and where the fix lives
- The crypto engine (
oxitls-core,oxitls-rustcrypto-provider,oxitls-adapter-rustls-rustcrypto).oxitls-coresupplies the shared traits, types, and theOsRngadapter.oxitls-rustcrypto-provideris the new fork carrying the CVE fix: it supplies TLS 1.3 cipher suites (AES-128-GCM, AES-256-GCM, ChaCha20-Poly1305), optional TLS 1.2 ECDHE-ECDSA / ECDHE-RSA suites (tls12feature, on by default), X25519 / secp256r1 / secp384r1 key exchange, ECDSA / Ed25519 / RSA (PKCS#1v1.5 + PSS) signing and verification, and an RFC 9001 §5.4 QUIC header-protection module.oxitls-adapter-rustls-rustcryptosits unchanged on top, and is where the OCSP and SCT hardening in this release actually lives (verifier::ocsp_client,verifier::sct). - Trust anchors (
oxitls-webpki-roots,oxitls-native-certs).oxitls-webpki-rootsstays Mozilla-roots-only — bundled WebPKI roots, an LRU intermediate-certificate cache, and expiring-roots support, all FFI-free.oxitls-native-certsis the dedicated quarantine crate for OS-native trust stores (Security.framework, SChannel, a PEM bundle on Linux) — opt-in, added directly only when you need it. - Opt-in bounded FFI (
oxitls-adapter-aws-lc,oxitls-adapter-pkcs11). The aws-lc-rs adapter (FIPS, high throughput) and the PKCS#11 adapter (HSM / TPM, tested against SoftHSM) are standalone crates with bounded FFI — never facade features, never in the default closure. - The facade and its wings (
oxitls,oxitls-h2,oxitls-rcgen).ClientBuilder/ServerBuilderare the ergonomic front door;oxitls-h2adds HTTP/2 over TLS with a generic stream type;oxitls-rcgengenerates Pure-Rust X.509 certificates. All three inherit the CVE fix automatically — none of them touchwebpkidirectly.
The cryptographic primitives underneath all of it — AEAD, hash, MAC, signature, key exchange — come directly from RustCrypto’s own audited crates (aes-gcm, chacha20poly1305, p256/p384, ed25519-dalek, rsa, sha2), vendored inside oxitls-rustcrypto-provider — no external crypto-primitives crate in between.
Getting Started
cargo add oxitls
A minimal async TLS client — nothing about this snippet changes in 0.2.1, but the CryptoProvider wired in underneath ClientBuilder::new() is now the CVE-clean fork automatically:
use oxitls::{ClientBuilder, TlsError};
#[tokio::main]
async fn main() -> Result<(), TlsError> {
let stream = ClientBuilder::new()
.server_name("example.com")
.connect("example.com:443")
.await?;
Ok(())
}
And the server side, with ALPN negotiation:
use oxitls::{ServerBuilder, TlsError};
#[tokio::main]
async fn main() -> Result<(), TlsError> {
let acceptor = ServerBuilder::new()
.with_cert_pem(cert_pem, key_pem)?
.with_alpn(&["h2", "http/1.1"])
.build()?;
Ok(())
}
Need certificates for local development? Enable the rcgen feature and generate them in Pure Rust — this path runs through oxitls-rcgen untouched by the CVE fix, since it never depended on webpki in the first place:
use oxitls_rcgen::{generate_self_signed_ed25519, generate_ca, SigningAlgorithm};
let leaf = generate_self_signed_ed25519(&["localhost", "127.0.0.1"])?;
let ca = generate_ca("My Root CA", SigningAlgorithm::EcdsaP256)?;
What’s New in 0.2.1
- Security: RUSTSEC-2026-0104 eliminated via the new
oxitls-rustcrypto-providerfork (webpki-free); OCSP staple validation now bindsCertIDto the certificate and issuer under verification and enforcesthisUpdate/nextUpdatefreshness, closing a replay bypass. - Added: the
oxitls-rustcrypto-providercrate itself — a complete Pure-Rustrustls::crypto::CryptoProvider(oxitls_rustcrypto_provider::provider()) with TLS 1.3 + optional TLS 1.2 suites, X25519/secp256r1/secp384r1 key exchange, ECDSA/Ed25519/RSA signing, and a QUIC header-protection module. - Changed: dependency bumps across the workspace —
oxihttpdev-dependency 0.1.4 → 0.2.0,oxiarc-deflate0.3.3 → 0.3.6,h20.4.14 → 0.4.15,p256/p384(workspace-level) 0.14.0-rc.9 → 0.14.0-rc.15,getrandom0.4.2 → 0.4.3,aws-lc-rs(bench/dev-only) 1.17.0 → 1.17.1;aes-gcm0.10.3 → 0.11.0 andchacha20poly13050.10 → 0.11 with internal call sites migrated from the deprecatedAeadInPlaceAPI toAeadInOut/encrypt_inout_detached(no behavior change); a newsha1workspace dependency feeds the OCSPCertIDhash recomputation; all workspace-internal crate versions bumped to 0.2.1. - Fixed:
extract_sct_extensionnow strips the RFC 6962 DEROCTET STRINGwrapper before parsing, so certificates carrying a real, X.509-embedded SCT list extension finally parse instead of silently failing Certificate Transparency verification.
Tips
- Upgrading is a version bump, not a migration. Bump to
oxitls = "0.2.1"(orcargo update -p oxitls-rustcrypto-providerif you pin transitively) — thepackage =rename meansoxitls-adapter-rustls-rustcryptoand everything above it keeps compiling with no source or feature-flag changes. - Re-run
cargo auditafter upgrading. RUSTSEC-2026-0104 should drop out of the report onceCargo.lockre-resolvesrustls-rustcryptoto theoxitls-rustcrypto-providerfork. - If you built custom OCSP soft-fail handling, re-test it. A staple that used to fall through to
Goodbecause validation merely scanned an unrelatedSingleResponsewill now correctly be rejected if it doesn’t bind to the certificate and issuer viaCertID— tighten any downstream logic that assumed the old, looser behavior. - If you verify embedded SCTs, this release is the actual fix, not just hardening. Before 0.2.1,
extract_sct_extensionnever successfully parsed an X.509-embedded SCT list, so Certificate Transparency verification via that path was silently a no-op. Upgrade before relying on it. - Expect two
p256/p384versions in yourCargo.lock— that’s intentional.oxitls-rustcrypto-providerpins RustCrypto’sp256/p384at 0.13.x to track the proven upstream fork exactly, while the rest of the workspace (oxitls-rcgen) uses 0.14.0-rc.x. Cargo resolves both without conflict. - TLS 1.2 ships on by default via the new provider’s
tls12feature. ECDHE-ECDSA / ECDHE-RSA suites are there out of the box alongside TLS 1.3 — nothing to enable.
This is the foundation
OxiTLS belongs to NoFFI — the COOLJAPAN initiative to replace every C / C++ / Fortran / -sys FFI dependency in the Rust ecosystem with a clean, memory-safe, 100% Pure Rust implementation. A release like 0.2.1, which removes a vulnerable dependency instead of merely papering over it, is that initiative working as intended.
OxiTLS sits underneath a growing list of sibling COOLJAPAN projects — all of them already pinned to oxitls = "0.2.1" (or one of its subcrates) at the time of this release: OxiHTTP, OxiQUIC, and OxiRPC carry it as their transport-security layer; OxiSQL depends on it directly, and its own Cargo.toml now notes that its CryptoProvider is supplied CVE-clean by this exact fork; OxiGDAL pulls in oxitls-core, oxitls-adapter-rustls-rustcrypto, and oxitls-webpki-roots individually; and OxiRS, CeleRS, MielinOS, and VoiRS round out the list. When a CVE fix lands in oxitls, it propagates to all of them on their next cargo update, with no code changes required on their side either.
Repository: https://github.com/cool-japan/oxitls
Star the repo if you want a TLS stack where a CVE gets removed from the dependency graph, not just patched around.
The era of shipping a vulnerable dependency because “we don’t hit that code path anyway” is over. Pure Rust TLS — sovereign, safe, and now provably free of RUSTSEC-2026-0104 — is here.
— KitaSan at COOLJAPAN OÜ July 17, 2026