Skip to content

Commit d61698d

Browse files
authored
Use native cert store on Android for rustls (nushell#17019)
1 parent 6800771 commit d61698d

File tree

1 file changed

+42
-1
lines changed

1 file changed

+42
-1
lines changed

crates/nu-command/src/network/tls/impl_rustls.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,17 @@ pub fn tls_config(allow_insecure: bool) -> Result<TlsConfig, ShellError> {
9999
let crypto_provider = CRYPTO_PROVIDER.get()?;
100100
let config = match allow_insecure {
101101
false => {
102-
#[cfg(feature = "os")]
102+
#[cfg(all(feature = "os", not(target_os = "android")))]
103103
let certs = RootCerts::PlatformVerifier;
104104

105+
// Use native cert store instead of platform verifier on Android, as we cannot use the
106+
// `platform-android-verifier-android` crate properly as we don't build a proper
107+
// android app but rather just a binary that is executed in termux.
108+
// Otherwise this guide would be really relevant:
109+
// https://github.com/rustls/rustls-platform-verifier/blob/1099f161bfc5e3ac7f90aad88b1bf788e72906cb/README.md#android
110+
#[cfg(all(feature = "os", target_os = "android"))]
111+
let certs = native_certs();
112+
105113
#[cfg(not(feature = "os"))]
106114
let certs = RootCerts::WebPki;
107115

@@ -115,3 +123,36 @@ pub fn tls_config(allow_insecure: bool) -> Result<TlsConfig, ShellError> {
115123

116124
Ok(config)
117125
}
126+
127+
/// Load certificates from the platform certificate store.
128+
///
129+
/// This method of loading certs is discouraged by the rustls team, see
130+
/// [here](https://github.com/rustls/rustls-native-certs).
131+
/// However this impl still works and is expected to work, especially for platforms that not
132+
/// properly support `rustls-platform-verifier`.
133+
#[cfg(feature = "os")]
134+
pub fn native_certs() -> RootCerts {
135+
use rustls_native_certs::CertificateResult;
136+
use ureq::tls::Certificate;
137+
138+
let CertificateResult { certs, errors, .. } = rustls_native_certs::load_native_certs();
139+
140+
// We only assert that we had no errors in a debug build.
141+
// We don't want to crash release builds when they encounter an error,
142+
// users rather have a broken http client than a crashing shell.
143+
debug_assert!(
144+
errors.is_empty(),
145+
"encountered errors while loading tls certificates"
146+
);
147+
148+
// This sadly copies the certs around but we cannot get the `CertificateDer<'static>` as
149+
// `&'static [u8]`.
150+
// Also internally is `ureq` loading the certificates into the `CertificateDer` format, oh well.
151+
let certs: Vec<_> = certs
152+
.into_iter()
153+
.map(|cert| Certificate::from_der(&cert).to_owned())
154+
.collect();
155+
let certs = Arc::new(certs);
156+
157+
RootCerts::Specific(certs)
158+
}

0 commit comments

Comments
 (0)