ge0rg / memorizingtrustmanager Goto Github PK
View Code? Open in Web Editor NEWA "plugin" for Android Java to allow asking the user about SSL certificates
License: MIT License
A "plugin" for Android Java to allow asking the user about SSL certificates
License: MIT License
MTM needs a comprehensive test suite with proper code coverage.
It is probably good to wait for #29 to get sorted out, so the test suite can plug into the UI API to simulate different behaviors.
Your library cannot be used together with Android sdk 23, as proguard throws an error:
Warning: de.duenndns.ssl.MemorizingTrustManager: can't find referenced method 'void setLatestEventInfo(android.content.Context,java.lang.CharSequence,java.lang.CharSequence,android.app.PendingIntent)' in library class android.app.Notification
This is a real show stopper - with that dependency your library cannot be used any more.
Issue #24 demonstrates that using "KeyStore" as app directory for MTM may not be the wisest choice. It should be renamed to something more unique to avoid collisions, e.g. "MTMKeyStore".
MTM should ensure that if an directory "KeyStore" already exists, then this is continued to use as key store directory. If not, ie. no "KeyStore" directory has been created yet, then the new default directory name should be used and such a directory be created.
Currently this will result in an ANR, as wait() is called on the UI thread.
There is a implicit conversion from array to a string in https://github.com/ge0rg/MemorizingTrustManager/blob/master/src/de/duenndns/ssl/MemorizingTrustManager.java#L413, which causes the hashCode to be printed and I'm not sure if that information is useful.
Example code for all APIs: https://github.com/Flowdalic/asmack/wiki/Truststore
I think it would be a good thing if we had an app providing a "Custom Certificate Management Service", based on your code. This app could provide a service for all third-party apps that allows to centrally verificate (custom) certificates.
Advantages:
Are you interested in discussing this and if we can agree on something, in providing such a service for DAVdroid? Please see also https://github.com/rfc2822/davdroid/issues/3 where this matter is discussed.
Some apps (F-Droid, ChatSecure, maybe others) want to have better control of when and how to ask the user about certificates, for example to suppress the dialog when connecting to a server for the first time (TOFU/POP approach).
For this, the startActivity()
/ interactResult()
"API" is insufficient, so it needs to be replaced with a real API. MemorizingActivity
will become the default / example implementation for how to use this interface.
Before this can be implemented, some things need to be specified:
Please contribute to the discussion!
Currently, MTM is using auto-increment integers for individual decisions. If an attacker gains a mechanism to inject decisions into MTM, he could easily enumerate the most probable IDs and cause a server to be trusted that should not.
A fix would be to change auto-incremented integers to UUID.randomUUID()
.
There might be environments where the key store file might be shared either
In both cases, thread synchronization within MTM is not enough. So I suggest to use file locking (if available on the platform and for the key store location) to prevent concurrent file access: a shared lock for reading and an exclusive lock for writing.
The new hostname verification popup shows the punycode-encoded hostnames, as this is the format used for SAN/CN. We need to pull in libidn or a comparable library to display the UTF8 hostnames to the user. IDN==PITA.
see my comment on #5
Running fdroidclient on my Motorola Xoom running CM 10.1-2014-02-16-NIGHTLY, MTM triggers the creation of two dirs based on the "KeyStore" name app_keystore
and app_KeyStore
. MTM ultimately ends up storing the file in app_keystore
, even though that is not the name specified. app_KeyStore
remains empty.
MTM should set the same to all lowercase to avoid issues related to bugs like this.
I try to use MemorizingTrustManager in the following scenario:
Connect through HttpsURLConnection to a custom web service allowing only my self-signed key (so far this works ok, i have removed any dialog-activities from MTM).
Then Android wants to use its own HttpsURLConnections (e.g. for Maps) but the problem is
that sometimes there is a fail-mix and Maps try to connect through the custom MTM...
Is there any way to use MemorizingTrustManager only for one connection and then use the default Android Mechanisms (e.g. not use MTM for application context but use only for a method)
At the moment, when several threads (for instance, synchronization workers called by Android) with MTM simultaneously access a host with unknown certificate, multiple decision activities will pop up, so the user will have to do the same decision multiple times. This makes it look like the application is not working correctly.
If there's already a pending decision for a given certificate, this decision should be waited for/used instead of creating a new one.
as it prevents those components from getting gc'ed.
The type of the master
field should be changed to Application.
The certificate verification dialog needs to show the cert fingerprint to allow for a proper verification by the user.
In some situations it is useful to directly present the Dialog without a notification, even if the connection is performed from a service (i.e. if your app is in the foreground right now).
This should be supported with some kind of activity/context stacking, maybe.
In the MTMExample project, the project.properties contains target=android-3
. This makes the project unbuildable since the AndroidManifest.xml includes android:targetSdkVersion="7"
. targetSdkVersion was added in android-4.
To fix, set target=android-4
or later in project.properties.
Congratulations on long-awaited updates!
Now I see the following issue:
> Lint found errors in the project; aborting build.
Fix the issues identified by lint, or add the following to your build script to proceed with errors:
...
android {
lintOptions {
abortOnError false
}
}
...
The first 3 errors (out of 24) were:
res/values/strings.xml:3: Error: "mtm_security_risk" is not translated in "eu" (Basque), "de" (German), "no" (Norwegian), "fi" (Finnish), "ru" (Russian), "fr" (French), "es" (Spanish), "iw" (Hebrew), "tr" (Turkish), "zh" (Chinese) [MissingTranslation]
<string name="mtm_security_risk">Warning: Potential Security Risk</string>
~~~~~~~~~~~~~~~~~~~~~~~~
res/values/strings.xml:7: Error: "mtm_trust_certificte" is not translated in "eu" (Basque), "de" (German), "no" (Norwegian), "fi" (Finnish), "ru" (Russian), "fr" (French), "es" (Spanish), "iw" (Hebrew), "tr" (Turkish), "zh" (Chinese) [MissingTranslation]
<string name="mtm_trust_certificte">Do you trust this certificte? It will be used to verify all listed names.</string>
~~~~~~~~~~~~~~~~~~~~~~~~~~~
res/values/strings.xml:10: Error: "mtm_valid_for" is not translated in "eu" (Basque), "de" (German), "no" (Norwegian), "fi" (Finnish), "ru" (Russian), "fr" (French), "es" (Spanish), "iw" (Hebrew), "tr" (Turkish), "zh" (Chinese) [MissingTranslation]
<string name="mtm_valid_for">Certificate valid for:</string>
~~~~~~~~~~~~~~~~~~~~
Please also note of certificte
typo
MTM right now only catches non-trustworthy certificates. However it needs to catch invalid hostnames and other invalidities like expired certs as well.
It would be much more comfortable for users of the library if they could just add it as a maven dependency instead of integrating it at the source level. For this it should be published in a public repository like jcenter or maven central.
How can a user of an app that utilizes MTM
in fdroidclient 0.71 with the TrustManager code changed to just this:
MemorizingTrustManager memMgr = new MemorizingTrustManager(getApplicationContext());
I get a crash on the TOFU prompt when fdroid first is installed and launched, and tries to connect to f-droid.org. The first bug is that it is trying to prompt on f-droid.org, since it has a valid CA-signed cert. The second bug is that when the TOFU prompt crashes, then MTM trusts the cert that it had previously prompted about, but that prompt crashed! So the second time, fdroidclient connects to f-droid.org, even though there is a stacktrace. All of these stacktraces are here:
https://gitlab.com/snippets/1881
Something like:
public boolean checkCertificate(X509Certificate certificate, String hostname) {
try {
if (certificate.equals(appKeyStore.getCertificate(hostname.toLowerCase(Locale.US)))) {
return true;
}
return interactHostname(certificate, hostname);
} catch (KeyStoreException e) {
LOGGER.error("error while checking certificate", e);
return false;
}
}
Hi,
I am trying to integrate MTM in an Android Studio project with gradle.
Can you assist me in integrating it? I added "android.library.reference.1=submodules/MemorizingTrustManager" to gradle.properties (since I don't have a default.properties - is that correct?).
Unfortunately it cannot resolve the name of the activity, when I add it to the AndroidManifest.xml of my app.
Any idea?
Thanks folks!
MemorizingActivity shows an AlertDialog.Builder dialog currently, causing some issues on orientation changes and having a small background window behind.
Hello,
I'm trying to use MemorizingTrustManager with HttpsUrlConnection (setSSLSocketFactory, setHostnameVerifier). It's a quite simple setup so I don't think I've done anything wrong; it' works quite well, but there is one problem:
When clicking on "Cancel" (= the certificate shall not be used), the HttpsUrlConnection (I think it's the getInputStream()
method) takes forever and according to adb, there's an endless loop + a memory leak, too.
Have you ever heard of such issues with HttpsUrlConnection and "Cancel", or do you know a working example of HttpsUrlConnection + MTM?
Thanks for your work.
Hello,
We have seen increasing problems with MTM in DAVdroid. Honestly, I don't know how to start debugging (except from dissecting the whole code line for line).
The problem is that MTM doesn't remember the "Always" click in the "Accept certificate?" dialog. As far as I have found out, it's not a key store problem, but related to how MTM GUI works (maybe some kind of thread synchronization problem?). DAVdroid uses a global (process-wide) MTM singleton in various components (Activities, Services etc.) and various threads. There are also up to two processes (a normal process and a :sync
process), so there might be two singletons sharing the same key store.
When MTM is called by the customized okhttp HttpClient, it correctly shows the "Accept certificate?" dialog. However, as soon as I click the "Always", button, I see this log message:
E/MemorizingTrustManager: interactResult: aborting due to stale decision reference!
and MTM ignores the click.
Do you have any idea what this could be or how I could start debugging it?
In many use cases, apps may want to delete all MTM-trusted certificates (especially if they don't provide a UI that allows to view and edit all trusted certificates, but only a "Reset all trusted certificates" option).
Currently, there's getCertificates()
and deleteCertificate()
, so we can iterate through all certificates, but I think a deleteCertificates()
method that deletes all certificates would be useful.
I can provide a pull request for that if you like, but it may take some time.
In order to decide whether the questionable cerficate is correct, a user would need certification details, including the fingerprint.
As far as I could see in the screen shots and the source code, these details are not displayed. Is this intentionally?
I have successfully used the MTM to connect to a web server, and I would also like to use it to display self-signed certificates for a non-HTTPS connection I make manually. I have an SSL verify callback that reaches up into the UI and will even block on a call to checkServerTrusted(), but no dialog is ever shown.
Should this work and I'm just not doing it right?
// initialize the MTM with an x509 store containing pinned certificates.
MemorizingTrustManager mtm = myObj.getMemorizingTrustManager();
try {
// here, I have tried with and without calling bindDisplayActivity
//mtm.bindDisplayActivity(myActivity.instance());
Log.d("I am printed");
mtm.checkServerTrusted(certList, "ECDHE_RSA");
Log.d("I am NOT printed");
} catch (Exception e) {
Log.d("MTM exception: " + e);
}
Thanks for any response.
Is MTM capable of handling simultaneous requests from multiple threads? For instance, synchronization adapters may be called by Android in several simultaneous threads. In this case (when a user interaction is required for multiple threads at the same time), I guess there should be only one dialog at a time and its decision should be used for all threads properly.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.