Wiki

Version 6 (hans, 07/30/2014 11:00 pm)

1 1 hans
h1. Trusted @Intent@ Interaction
2 1 hans
3 2 hans
* background: "Improving trust and flexibility in interactions between Android apps":https://guardianproject.info/2014/01/21/improving-trust-and-flexibility-in-interactions-between-android-apps/
4 2 hans
* source: https://github.com/guardianproject/TrustedIntents
5 2 hans
6 1 hans
the approaches to implementing the trust checking
7 1 hans
* pinning
8 1 hans
* TOFU/POP
9 1 hans
10 1 hans
tokens to check
11 1 hans
* the package ID of the app
12 1 hans
* the signing key of the app (see "android:protectionLevel":https://developer.android.com/guide/topics/manifest/permission-element.html)
13 1 hans
* a Chooser with a pinned list of package names (like PixelKnot)
14 1 hans
* the hash of the APK
15 1 hans
** needed to verify that the APK has not been modfied "ref":http://arstechnica.com/security/2013/07/google-patches-critical-android-threat-as-working-exploit-is-unleashed/
16 1 hans
** test exploit https://gist.github.com/poliva/36b0795ab79ad6f14fd8
17 1 hans
** http://www.saurik.com/id/17
18 1 hans
19 1 hans
20 1 hans
h3. When to Verify?
21 1 hans
22 1 hans
There are two good opportunities for verifying senders and receivers: at install and on each @Intent@/@startActivity()@ interaction.  Running the verify on install means that it is rarely run but means more complicated code.  Running the verify on each @Intent@ interaction means the verification is run every time, but the code should be much simpler.  Since the point of this system is security, simpler code is more important than execution efficiency.
23 1 hans
24 1 hans
25 1 hans
h3. Chained Validation Methods
26 1 hans
27 1 hans
Validation is based a token.  If the token does not exist in a given step, then the check goes on to the next step.  If the token does have an entry but it does not match, then validation stops and an error is thrown.
28 1 hans
29 1 hans
# check pins
30 1 hans
# check TOFU/POP
31 1 hans
# prompt user
32 1 hans
33 5 hans
h2. Ensuring the receiver of an @Intent@ is trusted
34 1 hans
35 1 hans
If data needs to be sent to another app and the receiving app must be trusted.  For example, if your app uses an OpenPGP providing app, then the sender wants to be sure that the receiver is the right app.
36 1 hans
37 1 hans
* @isIntentReceiverTrusted()@
38 1 hans
* @startTrustedActivity()@
39 1 hans
* @startTrustedActivityForResult()@
40 1 hans
* @bindTrustedService@
41 1 hans
* @onActivityResult()@ would then also handle validation problems and prompts
42 1 hans
* maybe @onTrustedActivityResult()@?
43 1 hans
44 5 hans
h2. Ensuring the sender of an @Intent@ is trusted
45 1 hans
46 1 hans
Provide a method for a receiver to verify that the sender is the right one.  For example, with ChatSecure it will become possible for other apps to send data via OTRDATA.  Once the user has clicked "Accept Always" then ChatSecure should remember that and verify that each incoming @Intent@ is allowed to be processed.  Another example is ChatSecure allows apps to send an @Intent@ to create an account.
47 1 hans
48 3 hans
The hard part is that Android does not provide a method to tell where an @Intent@ came from by default.  The supported way of doing it is setting a value in @startActivityWithResult()@ to check.
49 1 hans
50 3 hans
* @isSenderTrusted(Intent intent)@
51 5 hans
* http://www.unwesen.de/2011/04/10/android-intent-sender-verification/
52 4 hans
* @getCallingActivity()@ works if @Intent@ was sent using @startActivityWithResult()@ "[1]":https://stackoverflow.com/questions/15517820/android-validate-the-identity-of-intent-sender
53 4 hans
* @RecentTaskInfo@ might provide enough info otherwise "[2]":https://stackoverflow.com/questions/3304304/how-to-get-the-sender-of-an-intent/14249936#14249936
54 1 hans
* Both service intents and activity intents should be handled
55 1 hans
** Look into @Binder.getCallingPid / getCallingUid@
56 1 hans
** If all else fails, might need an auth token exchange
57 1 hans
58 6 hans
59 6 hans
h4. Open Questions
60 6 hans
61 6 hans
* is it possible to @setPackage()@ or set the @ComponentName@ in an @Intent@ then send it to a different app/@Activity@?
62 6 hans
63 6 hans
64 1 hans
h2. TOFU/POP callbacks
65 1 hans
66 1 hans
For using TOFU/POP validation rather than pinning, there needs to be some callbacks to allow the app to display the relevant UI.
67 1 hans
68 1 hans
* @onFirstUse()@ - the first time a @packageName@ is seen
69 1 hans
* @onValidateFailed()@ - if there is a mismatch between the @packageName@ and the signing certificate
70 1 hans
71 1 hans
72 1 hans
h2. validation methods on @PACKAGE_ADDED@/@PACKAGE_REPLACED@/@PACKAGE_CHANGED@
73 1 hans
74 1 hans
* calculating the APK hash is heavy because it has to read the whole APK
75 1 hans
* this can be done on when receiving the @Broadcast@s from the system
76 1 hans
* then a framework handles tracking this
77 1 hans
* only verifies signing key or hash when the app is installed/upgraded
78 1 hans
* lightweight version of @getTrustedIntent()@ and @startTrustedActivity()@
79 1 hans
* trusts Android system entirely
80 1 hans
* app must include changes to @AndroidManifest.xml@ to register @BroadcastReceiver@
81 1 hans
82 1 hans
83 1 hans
h2. sources of relevant code
84 1 hans
85 1 hans
* "PackageManager.addPermission":https://developer.android.com/reference/android/content/pm/PackageManager.html#addPermission(android.content.pm.PermissionInfo)
86 1 hans
* "Intent.ACTION_PACKAGE_ADDED":https://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_ADDED
87 1 hans
* https://github.com/moxie0/AndroidPinning
88 1 hans
* https://github.com/ge0rg/MemorizingTrustManager
89 1 hans
* https://github.com/guardianproject/ICTD/blob/master/src/info/guardianproject/ictd/ICTD.java#L62 (InformaCam)
90 1 hans
* martus-android's version of OrbotHelper.java
91 1 hans
* http://www.unwesen.de/2011/04/10/android-intent-sender-verification/
92 1 hans
* https://github.com/commonsguy/cw-omnibus/tree/master/MiscSecurity
93 1 hans
** The SigDump project lists all packages -- tapping on one decodes the "signature" and dumps the signature as a binary
94 1 hans
** The SigCheck project checks another app's "signature", comparing it to a known good value held as a raw resource (e.g., one dumped via SigDump).
95 1 hans
96 1 hans
h2. Use Cases
97 1 hans
98 1 hans
h3. Trusted Processing App
99 1 hans
100 1 hans
Martus needs to have strongly integrated, trusted camera app.  In this case, the Martus app will always initiate the camera @Activity@ by verifying the recipient before sending the explicit @Intent@.  The receiver is then expected to reply with the media directly to Martus.
101 1 hans
102 1 hans
An app wants to include a whitelist of trusted OpenPGP provider engires. Gnu Privacy Guard and OpenKeychain are both trusted, so the app includes pins for the signing certificates for both Gnu Privacy Guard and OpenKeychain.  This app will then only send data to be encrypted or decrypted to APKs that have been signed by those pinned signing certificates.
103 1 hans
104 1 hans
h3. Per-app permissions
105 1 hans
106 1 hans
InformaCam aims to be engine that provides verifiable media to any app.  It has app-specific media stores and keys.  When an app calls InformaCam the first time, InformaCam will register the sender, assign that sender a mediastore, and only send info from that mediastore to the app that is registered to it.  When sending media from a given mediastore, InformaCam will verify that it is sending to the trusted recipient for that mediastore.
107 1 hans
108 1 hans
h2. related idea for upgrading an APK's signing key
109 1 hans
110 1 hans
# create an APK with new package ID and signed by new key
111 1 hans
# both old and new APKs are installed at the same time
112 1 hans
# old one grants the new one perms to read all data based on hash pin