ver 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
- 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.
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.
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.
For 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.