Integrating Crypto Identities with Android


alberti cipher diskver the past couple of years, Android has included a central database for managing information about people, it is known as the ContactsContract (that’s a mouthful). Android then provides the People app and reusable interface chunks to choose contacts that work with all the information in the ContactsContract database. Any time that you are adding an account in the Settings app, you are setting up this integration. You can see it with Google services, Skype, Facebook, and many more. This system has a lot of advantages, including:

  • a unified user experience for finding and managing data about people
  • apps can launch common interface dialogs and screens for working with that database without having to write custom versions (launching Activitys via Intents
  • streamlined methods for building custom UIs based on the contacts database

With our work porting GnuPG to Android, we want Gnu Privacy Guard for Android to be fully integrated into the Android experience. Gnu Privacy Guard registers itself as a handler for all OpenPGP file and data types in Android, so users can work with these files using standard Android methods like Share/Send buttons. Or users can start by finding the person to encrypt to in the People app, then choosing the file. These flows make it intuitive to Android users, and means we have to write less code because it taps into existing Android systems. With the past release, v0.2, we laid the foundations for having the GnuPG keyring integrated into this contacts database. The next release, v0.3 will improve contacts integration a lot.

All of these contacts come from the GnuPG keyring being synced to the ContactsContract.  Nathan's contact is made up of combined info from Gnu Privacy Guard and Google. To encrypt a file to the author, select Encrypt File to... on his contact page.

All of these contacts come from the GnuPG keyring being synced to the ContactsContract. Nathan’s contact is made up of combined info from Gnu Privacy Guard and Google. To encrypt a file to the author, select Encrypt file to… on his contact page.

One of the concerns that has been voiced about integrating with the ContactsContract database is that all the data put there will be then uploaded to the other accounts, like the Google account of the phone, or other accounts. As far as we can tell, there is no automatic syncing of data between accounts in the ContactsContract, instead it is a system of individual, local databases. We have not confirmed this with a code audit whether there is any data leakage from ContactsContract, and would love to hear more information on that. There is a layer of matching rules for locally merging those local databases into a single, unified view of that data. A good example of this unified data view in action is the built-in People app. It will show data from all of the local databases, and it will link profiles together in a single view based on programmatic rules that look at email addresses, names, etc. In any case, Gnu Privacy Guard only syncs one way. It treats the GnuPG keyring as canonical and clones the GnuPG keyring contacts to the ContactsContract whenever a sync is run. The sync process never reads from the ContactsContract, and currently no data is ever imported from it. So at the very least, the ContactsContract should not serve as a point to inject data into the GnuPG keyring.

The ContactsContract builds up the complete view of all contacts based on RawContacts provided by each account type, which are in turn built up of standard data types like name, email, phone number, etc.

The ContactsContract builds up the complete view of all contacts based on RawContacts provided by each account type, which are in turn built up of standard data types like name, email, phone number, etc.

One unexplored idea is for apps that need to use crypto to use only the standard Android contacts API to fetch crypto identity information like public keys and fingerprints. For example, PGP email app K-9 could look up OpenPGP info at the same time it is looking in the contacts database for email addresses. It probably even makes sense for K-9 to offload even more to an OpenPGP provider, and have K-9 just query the PGP provider whether there is a signing key available, whether the receiver has a PGP key, etc.

It is also tempting to think about using a similar technique for storing other types of keys like OTR keys for secure chat. The hard part is that OTR has no method built-in to the key for verifying whether that key is trusted. OpenPGP has key signing and the Web-of-Trust, with all of its issues, but the OpenPGP security model is designed around untrusted methods of moving public key data around. Using the contacts database for moving around public key material for later verification will work equally well for OTR, OpenPGP, etc.

On a similar note, we are also working with Dominik Schürmann and the K-9 devs to create a common Android API for a generic OpenPGP provider. This is similar to the contacts system in recent versions of Android in that there is a single, central contacts system that any app can tap into for managing data related to people.

We have decided to go with Dominik Schürmann’s approach of using an AIDL API to an Android Service. AIDL does have some downsides mostly around it being overcomplicated. But AIDL is the main Android method for inter-process communication with Services, so we are stuck with it, more or less. The beautiful thing is that this arrangement will make it possible for apps to fully offload the crypto handling to the Service, including all the required GUI bits like passphrase prompting, progress dialog overlays, key selection, etc.

contacts with keysFor example of how this idea would work, we can look at K-9 email again. If an incoming email includes a public key or fingerprint, either of these can be sent to the OpenPGP provider for importing. An OPENPGP4FPR: URI will trigger downloading the public key from a keyserver. A public key contained in an attached file will be received by the OpenPGP provider via the Android file associations, which will then prompts the user to import it. When K-9 goes to send a OpenPGP-encrypted email to that new key, it checks the ContactsContract to see whether the recipient has a OpenPGP key. If so, it sends the email to the OpenPGP provider to be encrypted. The OpenPGP provider can then look up which key to use in it’s local keyring by using the recipient’s email address. If there are multiple keys for that email address, it prompts the user to choose. It could also base it’s choice on the OpenPGP trust level for that key.

These are currently all ideas for how GnuPG can be integrated into Android. Some of these are implemented and ready for you to try out on your device. The common OpenPGP provider idea is still very much a work in progress.