Multi signature for apk: double signing of upstream and F-Droid

I don’t trust to F-Droid (which is good, sorry).
The apk file that the F-Droid repository has may differ from the original upstream version.
Someone may hack the repository and upload own apk.

So I wish to have the upstream signature for the apk.

But the upstream may be compromised too. So I wish to have two signatures and the client should compare that the digest is the same.
With reproducible builds this should be possible.

I know that the PKCS7/CMS detached signature files allows multiple signers. The PGP should allow this too.
It looks like the Android apksigner “APK signature scheme v4” (Android 11+) has support for detached signatures
https://source.android.com/docs/security/features/apksigning/v4

The F-Droid client itself may be compromised too and ignore a signature or just upload an apk file from somewhere. So the signatures check ideally should be made by the Android itself. When I manually installing an apk file on my old Galaxy it just shows the app name but nothing about signatures. Maybe in newer Android this is improved somehow.

Compromising of a clients is less likely to happen without access to a phone.
But if the repo was hacked then the F-Droid may upgrade itself with the compromised version.
A hacked probably won’t have a signature if some of the F-Droid devs signs manually new versions.
But is this a case or the CI signs automatically?

Is the F-Droid app release performed manually, or it’s triggered automatically from git on a new tag?
What about other apps? Does anyone make some review of a new version? What if it was compromised?
The git allows to sign commits so at least we may know that the commits came from the same author.
Does F-Droid CI requires for a git commit signature?

Some critical apps (wallets, keychains, password managers, browsers) must have a review.
The reviewer may be a third party that also can approve the apk release by own signature.
It would be problematic to find such reviewers that aren’t affiliated with author and F-Droid and do have a time and willingness to review changes.
But for critical apps I believe it should be enough of volunteers.

Automatic upgrades for such critical apps is probably should be disabled by default. For a browser this may a bad idea because an upgrade may have a security fix. But for a wallet it probably would be better to notify a user about an upgrade but not install it automatically.

Today I wanted to install a wallet directly from a GitHub specifically to avoid a situation that the F-Droid will autoupdate it.
Then I disabled manually upgrades for my wallet app with “Ignoring upgrades” option,
but it was difficult to find it and I think such apps should be upgraded only manually by default.

Similarly, some apps may have a check for a new version and download it from somewhere.
The NewPipe does this and I do update it because it’s buggy, but I don’t really know from were the apk was downloaded.
So maybe the critical apps should have the own updater disabled and force a user to upgrade only from F-Droid.

Please clarify if it’s possible to improve the security.

All the things are possible, if you put your mind to it, so start helping: Contribute | F-Droid - Free and Open Source Android App Repository

1 Like

A good news, the double signing is already used. An author should build an apk and sign it. The F-Droid will build the apk too and compare it with the original. If the verification passed the F-Droid will publish the original apk with it’s own author’s signature. If the apk doesn’t have a signature then the F-Droid will add it’s own.
So we should ask the critical apps authors to sign and publish apk.

For example the PipePipe apk downloaded from F-Droid has own signature:

$ jarsigner -verify -verbose -certs InfinityLoop1309.NewPipeEnhanced_106403.apk 
- Signed by "CN=Jack Smith"

But the Bitcoin Wallet apk has the F-Droid sig:

$ wget https://f-droid.org/repo/de.schildbach.wallet_102100.apk
$ jarsigner -verify -verbose -certs de.schildbach.wallet_102100.apk 
- Signed by "CN=FDroid, OU=FDroid, O=fdroid.org, L=ORG, ST=ORG, C=UK"

The Bitcoin Wallet app previously had a released apk files with a signature but they are now removed and the app is available only from the F-Droid.

In it’s Build Metadata there are mentioned two (?) signing keys:

But in the Builds: I don’t see any version that had binary: with a URL to a build apk.

Another problem is automatic upgrade when the new version releases. It should be disabled and upgraded only after a manual review of changes. From the build metadata file I see AutoUpdateMode: None which is according to Build Metadata Reference means that I won’t be auto released on the F-Droid. But does anyone makes a review in the F-Droid team? Maybe we can create an auditors team from volunteers.

When a new release performed you have to manually add the Builds: entry or it can simply build from the new tag?

I also not quite understand why the UpdateCheckMode: None while it can be UpdateCheckMode: Tags so that a new version will be noticed.

Uploading the whole apk may be annoying for authors but also it requires for some place to upload (i.e. GitHub or other server that leads to centralization) and the F-Droid needs to download it. So maybe we can just extract META-INF/*.RSA and META-INF/*.SF files and then the F-Droid can include then into the apk itself.
The second thing is that the F-Droid actually can also add own signature into the apk but not sure if this will be accepted by Android. This is probably not necessary in the same time can make a user more confident but… I still don’t know how to see signatures of the apk when installing it in the Android.

Slight misunderstanding…

Because it uses extracted signatures (right side of the tree in the picture): Reproducible Builds | F-Droid - Free and Open Source Android App Repository - NO -YES -YES

Here, verify the signature: https://f-droid.org/repo/de.schildbach.wallet_102100_58dcd8a.apk

See… for these there are 2 APKs published, with the same version number. :wink:

/LE: on the website (there’s a bug) the first APK is F-Droid, the second is upstream signed

In the Client, the first APK and the default installed is the upstreamed signed one.

1 Like

Checked the Bitcoin Wallet apk signature:

- Signed by "CN=Unknown, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown"

The key is from 2011 so I hope the key really belongs to the author :slight_smile:

I found that with the App Manager you can see the signature right on the phone. In a Files long tap on the apk file and press / Options / Open With / App Manager: About app. Then on the Signatures tab you’ll find a list of all signatures and verification status.

The Reproducible Builds page explained a lot. So the app authors executes the fdroid signatures command and it adds the signatures into signatures folder. So the original apk is not uploaded to the F-Droid but it itself builds and copies signatures. I still don’t really get why the F-Droid uploads two versions.

This approach allows publishing both APKs signed by the (upstream) developer and APKs signed by F-Droid. This enables us to ship updates for users who installed apps from other sources than F-Droid (e.g. Play Store), while also shipping updates for apps which were built and signed by F-Droid.

But why not just always use the upstream apk?

Anyway it looks like users are almost safe and the double signature is in place. It only remains to disable auto updates or to have auditors who will approve a release before publishing in the store.

Because initially apps were signed only by F-Droid.

So when upstream reproducible builds came, users needed (and still need as we point in News | F-Droid - Free and Open Source Android App Repository) to UNinstall and REinstall the upstream signed one.

With 2 builds we have both old users (with F-Droid sig) and new usens (with upstream sig) updated without any un-re-installs.

1 Like