Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update rustls to 0.23 #70

Merged
merged 3 commits into from
Mar 25, 2024
Merged

Update rustls to 0.23 #70

merged 3 commits into from
Mar 25, 2024

Conversation

Ralith
Copy link
Collaborator

@Ralith Ralith commented Mar 8, 2024

Required for Quinn to update past rustls 0.21, so a release soon after would be appreciated. Also relaxes default feature requirements on rustls.

@djc
Copy link
Member

djc commented Mar 8, 2024

I think I tried this and it won't work on macOS...

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 8, 2024

This is difficult to test without CI working by default.

@complexspaces
Copy link
Collaborator

@Ralith I added you with the Triage role on the repository (it grants minimal issue and PR permissions). I can remove it once you've merged this and GitHub doesn't see you as an "untrusted contributor" here anymore but hopefully it doesn't bug you for now.

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 11, 2024

Android CI failing:

> Task :rustls-platform-verifier:connectedDebugAndroidTest

[DDMLIB]: An unexpected packet was received before the handshake.
[DDMLIB]: An unexpected packet was received before the handshake.
[DDMLIB]: An unexpected packet was received before the handshake.
[DDMLIB]: An unexpected packet was received before the handshake.

> Task :rustls-platform-verifier:connectedDebugAndroidTest
Starting 3 tests on test(AVD) - 9

org.rustls.platformverifier.CertificateVerifierTests > runRealWorldTestSuite[test(AVD) - 9] FAILED 
	org.junit.ComparisonFailure: A test failed. Check the logs above for Rust panics. expected:<[success]> but was:<[test failed!]>
	at org.junit.Assert.assertEquals(Assert.java:115)
Tests on test(AVD) - 9 failed: There was 1 failure(s).

Not sure how to interpret that. There aren't any panics that I can see. "An unexpected packet was received" sounds like a rustls-side issue. There seems to be some sort of test result artifact that might have details, but it doesn't look human-readable.

@zh-jq-b
Copy link

zh-jq-b commented Mar 11, 2024

It seems to be the same issue as reported here #68.

@cpu
Copy link
Member

cpu commented Mar 11, 2024

"An unexpected packet was received" sounds like a rustls-side issue.

I think these lines are unrelated noise. The same output has been happening on passing builds in the past. "ddmlib" looks like it's specific to the Android emulator<->Host debug bridge and so I think likely to be inconsequential to the Rustls tests.

It seems to be the same issue as reported here #68.

Yes, it is.

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 11, 2024

If the only CI failure is #68, can we consider this unblocked?

@Ralith Ralith force-pushed the update-rustls branch 2 times, most recently from b2cb2ec to 8c11739 Compare March 11, 2024 20:45
@cpu
Copy link
Member

cpu commented Mar 11, 2024

If the only CI failure is #68, can we consider this unblocked?

I don't know how @complexspaces feels but I think we wouldn't want to cut a release until main is passing CI so even if we merged this it would be blocked on #68.

I've made some progress and think I have a fix. Will update #68 shortly

@Ralith Ralith force-pushed the update-rustls branch 2 times, most recently from ca3f7b2 to 9f58145 Compare March 11, 2024 21:31
@cpu
Copy link
Member

cpu commented Mar 11, 2024

I've made some progress and think I have a fix. Will update #68 shortly

I think cherry-picking in 9872533 from #71 will sort the mac task out.

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 12, 2024

macos is hitting:

rustls default CryptoProvider not set

which is from the expect I added on CryptoProvider::get_default() calls. This stopped happening on other platforms when the rustls ring feature was enabled. I'd expect to have to call install_default either everywhere or nowhere; having that requirement vary across platforms is baffling.

@complexspaces
Copy link
Collaborator

That is extraordinarily strange. I tried comparing the output of cargo tree --edges features between macOS and Linux and nothing jumps out as "broken" in rustls direct dependency tree. The only difference is that there's no rustls-webpki.

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 12, 2024

Perhaps it's a test case ordering/global state issue. rustls tests suggest that None is the expected return value even when the feature is enabled:

https://github.com/rustls/rustls/blob/0398ac50fe18521da038aa39b55eec6c83450523/rustls/tests/process_provider.rs#L47-L58

I'll try setting defaults explicitly.

@Ralith Ralith force-pushed the update-rustls branch 4 times, most recently from 088f716 to 273b8a3 Compare March 12, 2024 01:22
@complexspaces
Copy link
Collaborator

It looks like its back to the Android failures 🎉 If you rebase on main Ci should be green at least. I merged #71 a few minutes ago.

@@ -438,7 +441,9 @@ impl Verifier {
pub(crate) fn new_with_fake_root(root: &[u8]) -> Self {
Self {
test_only_root_ca_override: Some(root.into()),
default_provider: rustls::crypto::ring::default_provider(),
default_provider: rustls::crypto::CryptoProvider::get_default()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these constructors should probably document that they're relying on the process-global crypto provider set via rustls?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think proceeding with this design would be user-hostile, as a typical use is likely to panic at runtime for users who haven't explicitly installed a default, which isn't normally required by rustls. I think a better solution would be for rustls to expose CryptoProvider::get_default_or_install_from_crate_features, which would let us Just Work as well as rustls itself does (although I have mixed feelings about how that breaks if multiple providers are enabled).

We could also reimplement the implicit default logic with local features in this crate, but that would put users at higher risk of accidentally enabling multiple providers (and potentially breaking any part of their code that relies on implicit defaults) if they don't take care to match features on rustls and this crate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this crate should probably just take an Arc as an argument.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works, though it undermines the convenience of rustls's implicit defaults if an idiomatic user has to go and deal with explicit provider handling for the verifier anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it might be cleaner if this operates at the level of a "parent" Arc<dyn ServerCertVerifier> rather than a CryptoProvider. But unfortunately right now WebPkiServerVerifier::builder() does require a non-empty set of roots, which makes it annoying to reuse for this purpose.

My other thought on this is: perhaps we should aim for windows.rs to use CryptVerifyMessageSignature (or similar) and for apple.rs to use SecKeyVerifySignature? That would minimise the chance that a certificate is accepted by the platform verifier, but the handshake can't complete because it the certificate is outside the subset that the rustls-webpki crate can parse.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My other thought on this is: perhaps we should aim for windows.rs to use CryptVerifyMessageSignature (or similar) and for apple.rs to use SecKeyVerifySignature?

I have thought about this before, but I'm still not sure I like the idea. It adds another "split" in the library's functionality set, especially on Windows where registry controls can influence what cryptographic operations the OS prefers/will use. This would make debugging harder, for example. So far I have only seen one cryptographic issue come in via bug report at work. Everything else has been missing trust roots, malformed X.509, etc.

Copy link
Collaborator Author

@Ralith Ralith Mar 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this crate should probably just take an Arc as an argument.

On review, this feels really awkward on *nix which doesn't actually need it.

It adds another "split" in the library's functionality set

Isn't exposing platform-specific behavior the whole point of this lib?

I think it might be cleaner if this operates at the level of a "parent" Arc rather than a CryptoProvider.

This makes a lot of sense to me.

But unfortunately right now WebPkiServerVerifier::builder() does require a non-empty set of roots, which makes it annoying to reuse for this purpose.

Could we relax this, or introduce an alternative verifier in rustls that has an empty root set but implements the other methods? Practically speaking this amounts to creatively delegating to rustls's get_default_or_install_from_crate_features, which I think is the best user experience.

rustls-platform-verifier/src/tests/mod.rs Show resolved Hide resolved
Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewing the diff I don't have any feedback above what djc has already flagged. Thanks again for picking this up Ralith 🎉

@Ralith
Copy link
Collaborator Author

Ralith commented Mar 15, 2024

I've added a commit that makes calls to CryptoProvider::get_default() lazy, which should ensure a good user experience without hard-coding a specific provider or breaking the API, because rustls will not attempt to verify a certificate until after it's been fully configured. The rare case of users who were previously passing in a provider explicitly and never touching the default implicitly might still see a panic, but can easily resolve it.

Long-term, I think it would be better for rustls to expose CryptoProvider::get_default_or_install_from_crate_features directly, since its use in e.g. WebPkiServerVerifier seems to be a tacit admission that it's the most user-friendly way for library code to get a provider. However, this change will let rustls-platform-verifier update and unblock downstream users like Quinn immediately without regressing usability.

Allows rustls's implicit defaults to be applied in
e.g. `ClientConfig::builder`, even if the verifier is constructed
beforehand. This allows the library to Just Work as in earlier
versions without breaking the API or baking in a particular provider.
rustls-platform-verifier/Cargo.toml Show resolved Hide resolved
@Lewiscowles1986

This comment was marked as spam.

Copy link
Collaborator

@complexspaces complexspaces left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay, LGTM.

@complexspaces complexspaces merged commit 0bd5440 into rustls:main Mar 25, 2024
15 checks passed
@cpu cpu mentioned this pull request Mar 25, 2024
4 tasks
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.

7 participants