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

example failed on Android for cert verification #70

Closed
king6cong opened this issue Mar 23, 2017 · 17 comments
Closed

example failed on Android for cert verification #70

king6cong opened this issue Mar 23, 2017 · 17 comments

Comments

@king6cong
Copy link

king6cong commented Mar 23, 2017

cargo dinghy run --example simple

thread 'main' panicked at 'called Result::unwrap() on an Err value: Http(Ssl(Failure(Ssl(ErrorStack([Error { code: 336134278, library: "SSL routines", function: "ssl3_get_server_certificate", reason: "certificate verify failed", file: "s3_clnt.c", line: 1264 }])))))', /checkout/src/libcore/result.rs:859
note: Run with RUST_BACKTRACE=1 for a backtrace.

@king6cong
Copy link
Author

Setting envar on android device like this solved the problem:

SSL_CERT_FILE=/sdcard/cacert.pem

But I wonder if is there a way to use the system wide ca cert file such as the ones in /system/etc/security/cacerts.

@seanmonstar
Copy link
Owner

Does Android always have certs installed there? If so, sounds like we could file in the openssl crate to look there when on Android?

@dten
Copy link

dten commented Mar 31, 2017

I am also getting this error which makes reqwest unusable for https on Android

@dten
Copy link

dten commented Mar 31, 2017

android's certificates are stored not as a pem but separate files with the filename being hash.n from looking / trying openssl won't read that format if you set SSL_CERT_DIR instead I've had to do as @king6cong did and provide a cacert.pem with my app's assets (i used the one from curl) and set SSL_CERT_FILE when the app starts. I don't like it but it works.

edit: this works when running cargo's tests from the command line, but setting it in an app isn't working

@seanmonstar
Copy link
Owner

Do you compile openssl yourself to ship with your app, or is it always available on Android?

If compiling yourself, the rust-openssl crate has instructions on configuring custom builds.

If it is always there, in an expected location and format, perhaps the rust-openssl crate could take a patch to look for it on Android.

@dten
Copy link

dten commented Mar 31, 2017

I'm compiling openssl and statically linking into a my cdylib crate which uses reqwest. Then calling some exposed functions through JNI. Http works but https requests fail with the above error. I'm going to keep at this and hopefully will come back with answer. Surely C++ using openssl also has this problem, but i cant find any one with the answer.

@seanmonstar
Copy link
Owner

So, to be clear, the instructions (here) from rust-openssl don't help? Perhaps once the steps are found, the instructions there could be updated with an Android section as well.

@dten
Copy link

dten commented Mar 31, 2017

Yes those settings are already in use otherwise you can't even get passed the openssl build script.
This error is much later and is more related to the SslContext not being able to verify certificates because it hasn't loaded Android's ca store

@king6cong
Copy link
Author

king6cong commented Mar 31, 2017

@seanmonstar @dten

I have looked into this today:

  1. setting env vars make the rust binary runnable under adb shell, but for the .so generated and embedded in android app, this does not work.
  2. add_root_certificate should have worked, but indeed not. I haven't figured out the reason. king6cong/rust-native-tls@56a78d0 @seanmonstar any suggestions?
  3. set_ca_file works, but a cert file is needed. Bundle it in android app assets makes it hard to get the cert file on Rust side (or any good ideas?). I write the cert file first and use set_ca_file with this file. Dirty but it works. king6cong/rust-openssl@6233276

Any suggestions are welcome. Rust SSL support on android is really a big deal. 😃

@dten
Copy link

dten commented Mar 31, 2017

Getting the asset shouldn't be too bad with android glue. https://github.com/tomaka/android-rs-glue/tree/master/examples/use_assets

Can't you set these from outside of reqwest

@king6cong
Copy link
Author

@dten Yeah, but load_asset(filename: &str) -> Result<Vec<u8>, AssetError> returned Vec which set_ca_file can not use directly.

@dten
Copy link

dten commented Mar 31, 2017

Ah yes sorry :) have to write it out somewhere first which would be awkward. I feel there should be a sensible answer for this. Investigation counties

@dten
Copy link

dten commented Apr 2, 2017

@king6cong add_root_certificate didn't work because Certificate::from_pem only returns the first certificate as far as I can tell. I tried include_str! instead of bytes and string split to add each key to the key_store and it worked.

my fork of rust-openssl has a commit that will read the system certs and it's working without any messing with files and assets
dten/rust-openssl@72da006
all i need to use it is this replace block in my Cargo.toml

[replace]
"openssl:0.9.10" = { git = "git://github.com/dten/rust-openssl" }

it should really also account for the user-added and user-removed keys that are elsewhere on the system but i haven't bothered yet

@king6cong
Copy link
Author

king6cong commented Apr 3, 2017

@dten That's awesome! 👍

In this way we can just use android system ca certs.
A little consideration regarding older Android versions:

according to http://wiki.cacert.org/FAQ/ImportRootCert

Before Android version 4.0, with Android version Gingerbread & Froyo, there was a single read-only file ( /system/etc/security/cacerts.bks ) containing the trust store with all the CA ('system') certificates trusted by default on Android. Both system apps and all applications developed with the Android SDK use this. Use these instructions on installing CAcert certificates on Android Gingerbread, Froyo, ...

Starting from Android 4.0 (Android ICS/'Ice Cream Sandwich', Android 4.3 'Jelly Bean' & Android 4.4 'KitKat'), system trusted certificates are on the (read-only) system partition in the folder '/system/etc/security/' as individual files. However, users can now easily add their own 'user' certificates which will be stored in '/data/misc/keychain/certs-added'.

Take older versions of Android into consideration and openssl on android will no longer be a problem :)

@seanmonstar
Copy link
Owner

Awesome work! I see you've filed an pull request to get this into the openssl crate, great. I'm going to close this issue then.

@Boiethios
Copy link

Hi guys,

maybe I am missing something, but when I try to use the API of a site with the default client:

let client = reqwest::Client::new();

I get a “certificate verify failed”. I tried to use the dangerous method like this guy:

let client = reqwest::ClientBuilder::new().danger_disable_hostname_verification().build()?;

but I get the exact same error. What am I missing there?

@seanmonstar
Copy link
Owner

@Boiethios the dangerous method disable only verification of the hostname in the certificate, but not that the certificate itself is trust by the current client configuration.

See #198 for what's holding up the ability to disable total certificate verification.

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

No branches or pull requests

4 participants