library for helping user install F-Droid after directly downloading an app
There are many ways around the world to share apps, often times people are getting APKs from wherever, and many app stores are just scrapping any APK sources they find. F-Droid provides the best delivery infrastructure for updates, so apps should tell the user to install it. Then they'll get regular updates from a trusted source.
I can see that app devs like to have the simpler model of just updating their own app, but there are so many advantages to the one time F-Droid install that I really want to drive people to installing F-Droid over having apps install their own updates. For example:
- F-Droid has built-in circumvention techniques (Tor, Nearby Swap, etc.)
- F-Droid will have a streamlined update procedure for lots of updates
- F-Droid can run without Unknown Sources when its a system app
This library should also be allowed in Google Play so that app developers do not need to make separate versions of the APK for Play. Lots of app stores scrape Play for APKs, so we want the library included there too. Here's the general flow of the library, when the app starts (i.e.
- detect if Google Play
com.android.vendingis installed and signed by the correct certificate, and if so, do nothing
- detect if F-Droid
org.fdroid.fdroidis installed and signed by the correct certificate, and if so, do nothing
- launch dead simple, verified F-Droid download and install process
The library API does not need to be complicated, I think this would probably cover it:
As for verification, the library should embed the F-Droid APK signing key and perhaps the GPG key and use that to verify what it downloads. The library would always verify using the APK signing certificate, and if spongycastle was included, then it would also verify the GPG signature. It would download F-Droid from:
One other thing that this library could do is serve as an update nag for people who have F-Droid installed. We could make F-Droid respond to a query Intent for the latest version available, then this lib would allow apps to nag the user whenever they used the app to install the update.
sounds good to me. Has anyone started working on this? I assume we would need a AAR library with minimal dependencies so as to not bloat the original application.
@paresh it would be great if you wanted to start working on this! We know have an awesome use case for it: official Firefox updater: https://bugzilla.mozilla.org/show_bug.cgi?id=1192279
OK, I have a cut of this implemented. Two questions:
Where should these modules go? I have set things up as if this code will go in a separate repo, since while this code relates to F-Droid, it is not real a part of
fdroidclient. IMHO, ideally, this and issue #852 (closed) code would go into the same repo, as they should share a
commonmodule (e.g., for HTTP downloading strategy code) and have the same audience (app developers who happen to distribute via F-Droid).
Where should ongoing discussion regarding these modules go? For example, I picked package names,
minSdkVersion, and stuff out of a hat, and we'll need to settle upon what you want the official values to be.
- I think this should be an official F-Droid project, so it should go in a repo in https://gitlab.com/fdroid does that work for you? Can't think of a name at the moment.
minSdkVersionis as low as you can easily go. 10 is great, 14 would be manageable, lower is not really important.
does that work for you?
Sure. It's your call.
Can't think of a name at the moment.
I have been calling it
app-utilsfor the moment, with classes in
org.fdroid.apputilsub-packages. All eminently rename-able.
With respect to
minSdkVersion, right now it is 14. 10 should be achievable, though I need to use
ACTION_INSTALL_PACKAGEon those older devices.
app utils sounds too value to me, how about "f-droid update utils"
It's your call. Name the repo what you want when you create it, and I'll adjust the rest to match.
So when talking about it, we'd say "you want to use the F-Droid app libraries to make your app always update, no matter where it was installed from"?
and if spongycastle was included, then it would also verify the GPG signature
I don't mess with PGP/GPG much (life's way too damn short...). Hence, I haven't done this before, but from what I can tell, I need the APK, the signature file, and the GPG public key. I know where to get the first two from the F-Droid server.
Where do I get the GPG public key from? This page gives me an email address and two fingerprints.
@commonsguy This is probably slightly more than you wanted / not all directly related to what you're doing, but it's good to know. I'm assuming (1) you/the reader knows near-nothing about gpg, so apologize in advance if this is basic, and (2) that you're using linux, although I'm pretty sure mac is the same and windows is similar (gpg is not installed by default in windows).
1. Get the public key
It's done this way for convenience. Automatic tools can have a list of keyservers and search them for keys, instead of having to know the individual location of each key.
gpg --search-keys firstname.lastname@example.org
It has a default list of key servers or you can specify one, like this:
gpg --keyserver https://pgp.mit.edu --search-keys email@example.com
2. Verify the key
Keys are colloquially identified by email address, but technically identified by fingerprint. You want to make sure you have the right one!
This is why key servers aren't a security problem. As long as you verify the fingerprint, you know you've got the right key, so it doesn't matter whether you trust the key server you got it from.
For reasons which I won't go into, it's a good idea to use subkeys, which are just regular keys that are linked to the primary key; you'll notice that the page you linked gives a fingerprint for both the primary key and the subkey they sign apks with.
gpg --fingerprint --fingerprint firstname.lastname@example.org
Then verify that the output is the same as the fingerprint on the f-droid site (what you linked). Putting
--fingerprinttwice just tells it to also show fingerprints of subkeys.
3. Decide that you trust the key
So far you've got a key, and you know it's the one the f-droid website told you about. What if the f-droid website got hacked? Do you trust it?
Trust isn't a technical thing. In this case, verifying the fingerprints with people here or in IRC is probably good enough.
More than you cared to know, feel free to skip this part
If you wanted to go one step further,
gpg --list-sigs email@example.com show you other people who have signed this key (ie, they've verified that it is in fact the f-droid key). Then you have to decide how trustworthy those people are. This is what's meant by the web of trust.
The world is a small place (6 degrees of separation and all that); if enough people sign each other's keys, you can probably trace a path from someone you know and trust in person to a stranger's key you found online. GPG's user-unfriendliness makes that a big "if", even for technical people, which is the essence of why gpg has problems. Now we're really off-topic. Bringing it back in...
4. Checking that an apk is signed with the right key
This is what you'd do from the desktop; you'll be doing the equivalent in Android.
apksigner verify --print-certs FDroid.apkwill output fingerprints that you can verify against the "Apk signing key" info on the page you linked above.
SHA256is the most important.
apksignerexecutable is in your
How about this for the naming:
- org.fdroid.appupdater aka "App Updater Library"
- org.fdroid.getfdroid aka "Get F-droid Library
For the public key to verify, it should be built into the library. You can get that by running
gpg --export firstname.lastname@example.org > email@example.com
As for names for the whole library, e.g. the git repo, here are some random ideas:
- trackdown (as in "track down updates for this app")
closedToggle commit list