Skip to content

Add rustls-platform-verifier support#170

Merged
Jake-Shadle merged 3 commits intoJake-Shadle:mainfrom
mpyuglgwkxcmodyrpo:platform-verifier-support
Feb 6, 2026
Merged

Add rustls-platform-verifier support#170
Jake-Shadle merged 3 commits intoJake-Shadle:mainfrom
mpyuglgwkxcmodyrpo:platform-verifier-support

Conversation

@mpyuglgwkxcmodyrpo
Copy link
Contributor

Hello! Thanks for the awesome tool. This has been a lifesaver for my development process and CI as I don't particularly like developing directly on windows and prefer non-Windows development environments.

This PR adds support for the rustls-platform-verifier, via the platform-verifier flag of ureq. This will enable xwin to use the system certificate store instead of just webpki-roots, enabling support for self-signed proxies and third party interception (think corporate proxy). The feature is enabled by passing a new feature flag to the build, so it will not affect any existing installations. The new flag is simply platform-verifier.

Let me know what you think. In my testing, the feature does work with the native-tls feature enabled, but I get the sense that it is falling back to rustls in that case, though I am unsure.

I added a #[allow(unused_mut)] to the default TLS config from ureq. I can refactor it if you prefer, but this was the way I chose to set both the root_certs and provider of the TLS config... If you have a more rusty way to do this I'd love to see it.

@erikbs
Copy link

erikbs commented Jan 24, 2026

I agree that this is useful. Unaware of this PR I was struggling with the same problem (xwin not accepting a corporate certificate) and was just about to submit a PR myself. I came to the same conclusion, to use rustls-platform-verifier, but I saw no reason to not enable using the system store by default (I will not claim that there is none). My suggestion is therefore a bit different:

--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,7 +22,7 @@ exclude = [
 [features]
 # By default we use rustls for TLS
 default = ["rustls-tls"]
-rustls-tls = ["ureq/rustls"]
+rustls-tls = ["ureq/rustls", "ureq/platform-verifier"]
 # If this feature is enabled we instead use the native TLS implementation for the
 # target platform
 native-tls = ["ureq/native-tls"]
@@ -52,6 +52,7 @@ regex = "1.11"
 ureq = { version = "3.0.0", default-features = false, features = ["gzip", "socks-proxy"] }
 memchr = "2.6"
 native-tls-crate = { package = "native-tls", version = "0.2", optional = true }
+rustls-platform-verifier = "0.6.2"
 # SHA-256 verification
 sha2 = "0.10"
 # Deserialization
--- a/src/main.rs
+++ b/src/main.rs
@@ -292,14 +292,14 @@ fn main() -> Result<(), Error> {
             builder = builder.proxy(Some(proxy));
         }
 
-        #[cfg(feature = "native-tls")]
-        {
-            builder = builder.tls_config(
-                ureq::tls::TlsConfig::builder()
-                    .provider(ureq::tls::TlsProvider::NativeTls)
-                    .build(),
-            );
-        }
+        builder = builder.tls_config(ureq::tls::TlsConfig::builder()
+            .root_certs(ureq::tls::RootCerts::PlatformVerifier)
+            .provider(if cfg!(feature = "native-tls") {
+                ureq::tls::TlsProvider::NativeTls
+            } else {
+                ureq::tls::TlsProvider::Rustls
+            })
+            .build());
 
         builder.build().new_agent()
     };

It offers simplicity (no need to compile a custom version to have this feature and does not require #[allow(unused_mut)]) at the cost of flexibility, but if the platform-verifier feature flag becomes enabled by default, I think that your suggestion offers an overall better solution than mine.

@mpyuglgwkxcmodyrpo
Copy link
Contributor Author

I don't know if it's a good idea to change any TLS validation behavior without user consent/acknowledgement. The system cert store is "trusted", sure, but it might just be better to let users opt-into the behavior.
Let's see what the maintainer says about it. It's really up to them.

I should just use if cfg! instead of a cfg attribute on the block. It's for this exact use case.

Copy link
Owner

@Jake-Shadle Jake-Shadle left a comment

Choose a reason for hiding this comment

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

Looking at this PR I just decided to remove all the features from this crate for simplicity, the use of the native cert store doesn't negatively impact normal users, but allows xwin to work in hostile corp environments without needing to enable a feature flag.

@Jake-Shadle Jake-Shadle merged commit 9db8240 into Jake-Shadle:main Feb 6, 2026
@erikbs
Copy link

erikbs commented Feb 6, 2026

Thanks! I just want to add that this is useful not just for corporate man-in-the middle environments, but also when downloading from a mirror, for example in an offline environment (for that, some sort of dry-run download that just dumps all the URLs could also have been a useful feature, but I assume that’s a bit out of scope for the tool, and using a Python script to get the URLs to mirror has worked for me).

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.

3 participants