Introducing TrustedIntents for Android


Following up on our research on secure Intent interactions, we are now announcing the first working version of the TrustedIntents library for Android. It provides methods for checking any Intent for whether the sending and receiving app matches a specified set of trusted app providers. It does this by “pinning” to the signing certificate of the APKs. The developer includes this “pin” in the app, which includes the signing certificate to trust, then TrustedIntents checks Intents against the configured certificate pins. The library includes pins for the Guardian Project and Tor Project signing certificates. It is also easy to generate the pin using our new utility Checkey (available in our FDroid repo and in Google Play).

Checkey displaying the signing certificate of ChatSecure

Checkey displaying the signing certificate of ChatSecure

We hope to make this process as dead simple as possible by providing developers with this library. TrustedIntents is currently set up as an “Android Library Project” but it could easily be a jar too, the code is currently quite simple, the plan is to add more convenience methods and also support for TOFU/POP in addition to pinning. For usage examples, check out TrustedIntentsExample and the test project under the test/ subdir of the TrustedIntents library source repo.

Checkey includes a simple method for generating the certificate pins. The pin is in the format of Java subclass of ApkSignaturePin, which provides all needed utility functions. The create the pin file, first install the app whose certificate you want to trust. Be sure to get it from a trusted source since you are going to be trusting the signing certificate of the APK that you have installed. Launch Checkey and select that app in the list, you will see the certificate details show up on the top. To generate the .java file for pinning Intents, select Generate Pin from the menu and send the resulting file to yourself. That file is the pin, include it in your project, then load it into TrustedIntents by doing in onCreate() or wherever is appropriate:
<br /> TrustedIntents ti = TrustedIntents.get(context);<br /> ti.isTrustedSigner(MySigningCertificatePin.class);<br />

How to generate a pin file with Checkey

How to generate a pin file with Checkey

Gathering all the edge cases

One of the things I’ve focused on in the TrustedIntents library is thinking about all the possible edge cases and how to check for them. It is rare that the main part of a security check algorithm fails, its almost always the edge cases that are the gotcha.

One example: TrustedIntents should properly check all signing certificates on an APK. From what I’ve seen, it is rare that APKs are signed by more than one certificate, but the spec allows for that. There might be exploits related to not handling that.

Another thing is that TrustedIntents uses the method that the Android code uses for comparing signatures: it does a byte-by-byte comparison of the signature byte arrays. Some apps area already doing something similar based on the hash of the signing certificate (i.e. the “fingerprint”). The Android technique will also be faster than hashing since the hash algorithm has to read the whole signature byte array anyway.

We’d love to have feedback, flames, comments, etc on any and all of this. Let us know how it works for you!