Add authenticated F-Droid user repositories and management CLI

Verify pinned JAR/CMS signatures, v2 index hashes and APK downloads; support signed v1 fallback and persist TOFU identities. Reuse the catalogue reducer and document repository publishing with offline and live verification evidence.

Co-Authored-By: GPT-6 Astra <noreply@openai.com>
This commit is contained in:
saphidandGPT-6 Astra committed 2026-09-28 21:06:06 +10:00
1 parent 268afccf05
commit 784a48f218
12 files changed
+903

No files matched your search

+14
View File
@@ -0,0 +1,14 @@
# F-Droid verification fixtures
`entry.jar` and `index-v1.jar` are synthetic RSA-2048/SHA-256 signed JARs,
including CMS signed attributes. `fingerprint.txt` identifies their throwaway
certificate. Their JSON describes org.example.app; `example.apk` is deliberately
plain test data, not an installable app. The v2 index includes incompatible
Android-31 and x86-only versions to exercise the shared reducer.
`izzy-entry.jar` was recorded from
https://apt.izzysoft.de/fdroid/repo/entry.jar on 2026-09-28. Its certificate
fingerprint matches the operator's published fingerprint:
3BF0D6ABFEAE2F401707B6D966BE743BF0EEE49C2561B9BA39073711F628937A.
It exercises an independent production JAR/CMS encoder without network access.
The index it references is not needed by this signature-only fixture test.
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
Fixture APK payload, deliberately not installable.
+1
View File
@@ -0,0 +1 @@
0e87b227cd414d7093fb150fda81f1754900f3abc810e6785d8e0767c6eb798a
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
{"repo": {"name": {"en-US": "Fixture"}}, "packages": {"org.example.app": {"metadata": {"name": {"en-US": "Example"}, "summary": {"en-US": "Offline fixture"}, "license": "MIT"}, "versions": {"1": {"manifest": {"versionName": "1", "versionCode": 1, "usesSdk": {"minSdkVersion": 21}, "nativecode": []}, "file": {"name": "/example1.apk", "sha256": "3e1e2658aef79aaf21aeb8d6705dbc5b251e51627bfdfc53650da50ed2c38c79", "size": 51}, "added": 1700000000000}, "2": {"manifest": {"versionName": "2", "versionCode": 2, "usesSdk": {"minSdkVersion": 30}, "nativecode": ["arm64-v8a"]}, "file": {"name": "/example2.apk", "sha256": "3e1e2658aef79aaf21aeb8d6705dbc5b251e51627bfdfc53650da50ed2c38c79", "size": 51}, "added": 1700000000000}, "3": {"manifest": {"versionName": "3", "versionCode": 3, "usesSdk": {"minSdkVersion": 31}, "nativecode": []}, "file": {"name": "/example3.apk", "sha256": "3e1e2658aef79aaf21aeb8d6705dbc5b251e51627bfdfc53650da50ed2c38c79", "size": 51}, "added": 1700000000000}, "4": {"manifest": {"versionName": "4", "versionCode": 4, "usesSdk": {"minSdkVersion": 21}, "nativecode": ["x86_64"]}, "file": {"name": "/example4.apk", "sha256": "3e1e2658aef79aaf21aeb8d6705dbc5b251e51627bfdfc53650da50ed2c38c79", "size": 51}, "added": 1700000000000}}}}}
Binary file not shown.