Skip to content

Switch rustls crypto provider from ring to aws_lc_rs - #3654

Open
ChihweiLHBird wants to merge 4 commits into
spinframework:mainfrom
ChihweiLHBird:zhiwei/ring-to-aws-lc-rs
Open

ChihweiLHBird wants to merge 4 commits into
spinframework:mainfrom
ChihweiLHBird:zhiwei/ring-to-aws-lc-rs

Conversation

@ChihweiLHBird

@ChihweiLHBird ChihweiLHBird commented Aug 8, 2026 •

Copy link
Copy Markdown
Contributor

Install aws_lc_rs as the process-wide provider at startup. ring is still compiled via transitive rustls features; removing it is a follow-up.

Replace the install helper with spin_tls::get_or_install_default_crypto_provider(), which returns the installed default, respecting a provider installed by embedders (the old helper would panic), and installs aws-lc-rs if none is set. The outbound client and trigger-http server TLS configs now build with aws_lc_rs provider explicitly.

Partially fix #3502

@itowlson
itowlson requested review from lann and rylev August 9, 2026 19:35
@lann

lann commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

rustls auto-detection would panic on paths that bypass Spin's entrypoints

Could you say more about this? Where would one need to bypass Spin's entrypoints? 🤔

@ChihweiLHBird

ChihweiLHBird commented Aug 10, 2026 •

Copy link
Copy Markdown
Contributor Author

rustls auto-detection would panic on paths that bypass Spin's entrypoints

Could you say more about this? Where would one need to bypass Spin's entrypoints? 🤔

Sorry... this is still a draft. The scenario in my mind was if another thing uses Spin as a crate and install ring as default. I know it's not supposed to be used this way, but in theory it might happen. So, I left that in draft and will refine it later.

@lann

lann commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

If something is embedding spin it should be able to pick the provider. If we're changing the default for spin up then that should just be scoped to the spin binary crate I think.

@ChihweiLHBird

Copy link
Copy Markdown
Contributor Author

@lann the original way expects the default is not installed:

rustls::crypto::ring::default_provider()
    .install_default()
    .expect("failed to install rustls ring crypto provider");

It's from my previous PR #3590

The implementation in this PR is theoradically safer even though the panic scenario is very unlikely to be triggerred.

@ChihweiLHBird ChihweiLHBird changed the title Switch rustls crypto provider from ring to aws-lc-rs Switch rustls crypto provider from ring to aws_lc_rs Aug 10, 2026
@lann

lann commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Right but that is only called from spin trigger implementations (which are effectively the root binary crate in this case).

@ChihweiLHBird

ChihweiLHBird commented Aug 11, 2026 •

Copy link
Copy Markdown
Contributor Author

@lann Sorry for the confusion. I looked into it again, and found my earlier explanation was wrong.

Flipping the workspace rustls feature to aws_lc_rs does not remove ring, so without these guards of installing default and build ClientConfig with a specific provider via builder_with_provider, it may panic because 2 providers are compiled in. In many code paths, e.g. some spin tests, who doesn't call the install default helper, will panic, if without builder_with_provider.

Four tests in crates/factor-outbound-networking/src/tls.rs and tests/factor_test.rs all build a ClientConfig without going through a Spin entrypoint. That's what the builder_with_provider calls guard.

I can also split the helper into install_default_crypto_provider() (entrypoints only) and default_crypto_provider() for the config builders. Does that sound like a good idea?

@ChihweiLHBird
ChihweiLHBird marked this pull request as ready for review August 11, 2026 06:07
@ChihweiLHBird
ChihweiLHBird marked this pull request as draft August 11, 2026 06:37
@ChihweiLHBird
ChihweiLHBird marked this pull request as ready for review August 12, 2026 02:59
@itowlson

Copy link
Copy Markdown
Contributor

@lann bump

Install aws-lc-rs as the process-wide provider at startup. ring is still compiled via transitive rustls features; removing it is a follow-up.

Since both provider features are now enabled, rustls auto-detection would panic on paths that bypass Spin's entrypoints. Replace the install helper with spin_tls::get_or_install_default_crypto_provider(), which returns the installed default - respecting a provider installed by embedders (the old helper would panic) - and installs aws-lc-rs if none is set. The outbound client and trigger-http server TLS configs now build with this provider explicitly.

Signed-off-by: Zhiwei Liang <zhiwei.liang@zliang.me>
@ChihweiLHBird
ChihweiLHBird force-pushed the zhiwei/ring-to-aws-lc-rs branch from 3c3196a to 7a6411e Compare September 22, 2026 20:59
The rebase onto main picked up rustls-webpki 0.103.14, which requires aws-lc-rs 1.18, while Cargo.lock still pinned aws-lc-rs 1.17.1 from the pre-rebase resolution. The lock file merged cleanly but no longer resolved under --locked, so `make install` and `cargo vet --locked` failed while CI's unlocked builds silently rewrote it.

Regenerate the lock file with `cargo update -p aws-lc-rs`, which also bumps aws-lc-sys to 0.45.0. Cargo also re-pinned tempfile's getrandom dependency from 0.4.3 to 0.3.4; both versions stay in the lock file.

Signed-off-by: Zhiwei Liang <zhiwei.liang@zliang.me>
rumqttc builds a rustls ClientConfig eagerly while parsing an mqtts:// URL, which makes rustls pick the process-wide CryptoProvider from crate features if none is installed. With both ring and aws-lc-rs compiled in, that choice is ambiguous and rustls panics. The spin CLI and the trigger commands install a provider at startup, but NetworkedMqttClient::create called directly, as an embedder or a test would, panicked instead of returning a client or an error.

Call spin_tls::get_or_install_default_crypto_provider() before parse_url, matching the outbound HTTP client and HTTP trigger TLS configs. Add a regression test in its own test binary so the process starts without an installed provider.

Signed-off-by: Zhiwei Liang <zhiwei.liang@zliang.me>
Most call sites only need to make sure a process-wide rustls crypto provider exists before rustls, or a library building its own rustls config, runs; only the outbound client and HTTP trigger TLS configs need the provider itself. Add spin_tls::install_default_crypto_provider() for the former and build get_or_install_default_crypto_provider() on top of it, so the entrypoints and the MQTT client no longer clone and discard an Arc.

Signed-off-by: Zhiwei Liang <zhiwei.liang@zliang.me>

This branch has not been deployed

No deployments
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.

FIPS Support

3 participants