@@ -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