Implement VettedContextWrapper, VettedActivity, and kin
These classes would validate inbound Intents (e.g., onCreate()/onNewIntent() of activity, onHandleIntent() of service) and outbound Intents (e.g., startActivity()), to confirm that they conform to a configurable set of policies, to confirm that the partner app is someone that we trust.
Have an VettingPolicyBuilder to construct a chain of such rules, based upon the model used with TrustPolicyBuilder. Stock policies should include:
- Partner signature hash matches pinned value
- Partner signature hash matches previously-seen value (trust-on-first-use/memorization), with optional "hey! this is first use!" hooks for user confirmation
- Partner whole-APK hash matches pinned value
- Partner whole-APK hash matches previously-seen value (trust-on-first-use/memorization), with optional "hey! this is first use!" hooks for user confirmation
- Partner holds certain permissions (for cases where
android:permissionis insufficient, such as holding N permissions)
Ensure that the policies have enough hooks for app-specific Intent content rules (e.g., secrets leakage via extras).
Ensure that the policies also support a "conditional-trust-on-first-use" model, where we soft fail (to allow the UI to alert the user for a validation check), then can validate the request in a background thread. For example, this would support an online catalog of known signature/whole-APK hashes. This would also be useful for a licensing check (e.g., will only inter-operate with third parties publishing a per-package license key in a well-known location, with Web service check of license key). Ideally, have some sort of cache of this stuff, so we can avoid the "conditional" part via a preload (e.g., we only interoperate with confirmed-good plugins for our hub-and-spoke model, where we download the roster of plugins periodically).
For outbound requests, this implies an explicit Intent, so we know who the partner is. Provide an VettedActionProvider and a VettedChooser to help with this. If handed an implicit Intent, fail if there are multiple matching components (e.g., queryIntentActivities()).
For inbound requests, use Binder.getCallingUid(). Policies should indicate whether we support N apps with a shared user ID for callers (and, if so, how do we interpret the rest of the policies?).
Provide base classes (e.g., VettedActivity) that apply this stuff automatically. For outbound requests, can use a VettedContextWrapper as well. Everything should be available without inheritance though -- the base classes should be for convenience, nothing more.
The serious PITA will be working up a test harness for this.
This stuff is based on Facebook's presentation of having similar capabilities in their app, which (AFAIK) they have not (yet) released as open source.