Skip to content

chore(deps): migrate off unmaintained rustls-pemfile (RUSTSEC-2025-0134)#7

Merged
StefanSteiner merged 1 commit into
tableau:mainfrom
StefanSteiner:ssteiner/migrate-off-rustls-pemfile
May 18, 2026
Merged

chore(deps): migrate off unmaintained rustls-pemfile (RUSTSEC-2025-0134)#7
StefanSteiner merged 1 commit into
tableau:mainfrom
StefanSteiner:ssteiner/migrate-off-rustls-pemfile

Conversation

@StefanSteiner
Copy link
Copy Markdown
Contributor

Migrate off unmaintained rustls-pemfile

Summary

The rustls-pemfile crate is archived upstream — its README confirms the API will not be extended, and RustSec issued RUSTSEC-2025-0134 marking the crate as unmaintained. The functionality has moved into rustls-pki-types::pem, which rustls already re-exports as rustls::pki_types.

This PR replaces every call site in hyperdb-api-core with the PemObject trait from rustls::pki_types::pem, drops the workspace dependency, and removes the corresponding waiver from deny.toml and .cargo/audit.toml. It is a single atomic commit (c08ecf7).

What changed

Production code: hyperdb-api-core/src/client/tls.rs

Three call sites in rustls_impl::create_connector:

Call Before After
CA-cert loading (line 215) File::open + BufReader + rustls_pemfile::certs(...) CertificateDer::pem_file_iter(ca_path)
Client-cert loading (line 240) same shape CertificateDer::pem_file_iter(cert_path)
Client-key loading (line 252) File::open + BufReader + rustls_pemfile::private_key(...)?.ok_or_else(\"no private key found\") PrivateKeyDer::from_pem_file(key_path)

The new API opens and buffers the file internally, so the explicit File::open + BufReader plumbing falls away. The "no private key found" branch also goes away — from_pem_file returns Error::NoItemsFound directly when the file is syntactically valid PEM but contains no key section, which is the same outcome the old code synthesized via .ok_or_else(...).

Net change in tls.rs: −21 lines, error coverage preserved.

Tests: hyperdb-api-core/tests/tls_tests.rs

Three call sites in start_echo_server parse PEM from in-memory &str buffers, so they migrate to pem_slice_iter / from_pem_slice rather than the file-based variants. The previous rustls_pemfile::private_key(...).unwrap().unwrap() (double-unwrap of Result<Option<PrivateKeyDer>, io::Error>) collapses to a single .unwrap() because PrivateKeyDer::from_pem_slice returns Result<PrivateKeyDer, Error>NoItemsFound is now a variant of the error enum rather than a None case.

Dependency graph

  • Removed from root Cargo.toml: rustls-pemfile = \"2.0\".
  • Removed from hyperdb-api-core/Cargo.toml: rustls-pemfile = { workspace = true }.
  • No new dependency addedrustls::pki_types is already in our direct graph via rustls = \"0.23\" (which re-exports rustls-pki-types 1.14.1, the same crate that owns the new PEM-parsing API). The pem module is gated behind the alloc feature (default-on), already enabled by our existing features = [\"std\", \"ring\", \"tls12\"].

grep -c rustls-pemfile Cargo.lock returns 0 post-merge.

Waivers

RUSTSEC-2025-0134 removed from both deny.toml and .cargo/audit.toml. This was the only entry whose underlying issue was "upstream is dead, must migrate." The remaining waivers (RUSTSEC-2024-0436 for paste, RUSTSEC-2023-0071 for rsa) and the forward-looking thrift CVE note are unchanged.

Docs

DEVELOPMENT.md had two stale references to rustls-pemfile in the dependency tables (lines 273 and 856 pre-PR). Both updated to reflect that PEM parsing now comes through rustls's re-exported pki_types::pem.

Why this is safe

  • No new crate added. rustls-pki-types was already pulled by rustls, rcgen, tokio-rustls, and reqwest. We just stop reaching for the unmaintained sibling crate.
  • Same parser implementation under the hood. rustls-pemfile 2.2.0's implementation was already a thin wrapper over rustls-pki-types::pem — the upstream maintainers folded it back into pki-types and archived the wrapper. Behavior is byte-for-byte equivalent.
  • All 15 TLS integration tests pass, including the seven rustls_tests::* cases that exercise both the migrated production paths (CA loading, mTLS) and the migrated test helper.

Verification

All gates run locally:

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test -p hyperdb-api-core --test tls_tests — 15/15 pass
  • cargo test --workspace --exclude hyperdb-api-node --exclude hyperdb-bootstrap (with HYPERD_PATH) — full workspace green
  • cargo test -p hyperdb-bootstrap — green
  • cargo deny check — clean (advisories ok, bans ok, licenses ok, sources ok) without the dropped waiver
  • cargo audit --deny warnings — clean
  • grep -c rustls-pemfile Cargo.lock0

Test plan

  • Full CI matrix (ubuntu-latest / macos-14 / windows-latest) green on this PR.
  • audit job stays clean — confirms RustSec advisory-db doesn't re-flag anything we removed the waiver for.
  • No downstream consumers of hyperdb-api-core need code changes — the public API surface (TlsConfig, rustls_impl::create_connector) is unchanged; only internal parsing implementation moved.

Out of scope

  • The remaining waivers (paste, rsa Marvin Attack, the forward-looking thrift CVE note) — preserved as-is per the rationale already documented in deny.toml / .cargo/audit.toml. Each requires a separate upstream resolution and is tracked independently.

The `rustls-pemfile` crate is archived upstream — its README confirms the
API will not be extended, and RustSec issued RUSTSEC-2025-0134 marking
the crate as unmaintained. The functionality has moved into
`rustls-pki-types::pem`, which `rustls` already re-exports as
`rustls::pki_types`.

This commit replaces every call site in `hyperdb-api-core` with the
`PemObject` trait from `rustls::pki_types::pem`:

* `hyperdb-api-core/src/client/tls.rs` — three call sites in
  `rustls_impl::create_connector`. CA-cert and client-cert loading now
  use `CertificateDer::pem_file_iter`, and the client private key uses
  `PrivateKeyDer::from_pem_file`. The new API opens and buffers the
  file internally, so the `BufReader` plumbing and the explicit
  `File::open` step go away. The "no private key found" branch also
  goes away — `from_pem_file` returns `Error::NoItemsFound` directly
  when the file is syntactically valid PEM but contains no key
  section.

* `hyperdb-api-core/tests/tls_tests.rs` — three call sites in
  `start_echo_server`. The tests parse PEM from in-memory `&str`
  buffers, so they now use `pem_slice_iter` / `from_pem_slice`.

The `rustls-pemfile` workspace dependency is dropped from the root
`Cargo.toml` and from `hyperdb-api-core/Cargo.toml`; no new dep is
added because `rustls::pki_types` is already in our direct dependency
graph via `rustls 0.23`. The corresponding waivers for
RUSTSEC-2025-0134 are removed from `deny.toml` and `.cargo/audit.toml`.

Verified: `cargo fmt --all --check`,
`cargo clippy --workspace --all-targets --all-features -- -D warnings`,
the full TLS integration suite (`cargo test -p hyperdb-api-core --test
tls_tests`, 15/15 passing), the workspace test gate, the
`hyperdb-bootstrap` test gate, `cargo deny check` (now clean without
the waiver), and `cargo audit --deny warnings`. Lockfile confirms
`rustls-pemfile` is fully gone.
@StefanSteiner StefanSteiner merged commit 3c50b04 into tableau:main May 18, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant