Open lberrymage opened 9 months ago
Question: How does the way the signing cert hashes get verified not prevent a compromised key that was rotated from being used to update the app? Since it says it must only contain one in the lineage. I know the Android docs say to do this but I'm a little confused and would like an explanation if you know :D
Sorry, can you clarify? I can't quite picture the situation you're describing.
An app is signed with a key. Let's say it gets compromised or it just has to be rotated to a newer key that is more secure. If the old key is cracked what's stopping it being put in the signing_cert_hashes and being accepted by the client?
Let's say the first certificate is "aaaa" and the second certificate is "bbbb".
The app developer rotates their app's cert from "aaaa" to "bbbb" and uploads a new update to the developer console. The console sees that the cert has been rotated, so it keeps the update from being published temporarily. The repository maintainer (myself) is notified of this, verifies the rotation locally (so the server isn't trusted), and updates signing_cert_hashes for the app from "aaaa" to "bbbb". The index is then signed and uploaded to the repository.
Someone cracks the key for cert "aaaa", gains access to Accrescent's servers, and replaces the legitimate app with a malicious copy signed with cert "aaaa".
When Accrescent downloads the app, it'll see that the app was signed with cert "aaaa". Provided it has an up-to-date repository index, it knows that signing_cert_hashes contains "bbbb", not "aaaa", so it rejects the update as invalid.
Does that answer your question?
Thanks, that answered my question. The wording seems to say that the app certificate must only be contained in the certificate lineage stored in signing_cert_hashes, no?
"If it contains exactly one item, the app was signed with one certificate, and the signing certificate lineage must contain the hash in signing_cert_hashes."
The certificate in signing_cert_hashes must exist somewhere in the app's certificate lineage. The full lineage isn't contained in signing_cert_hashes, just the latest cert in the lineage that Accrescent is aware of.
How should update changelogs be represented?
Can't it be in {version_code}/metadata.json or another file in {version_code}? Since it would be specific to the version_code. Is there a reason that won't work?
That would make sense if we only want to show the latest changelog entry in the UI. We may want to have the option to view past changelog entries, but I think only being able to view the latest makes sense for now.
If we ever want to view past changelog entries there could just be version code directories in one versions directory or something.
Regarding delta updates, is there anything wrong with just placing the delta for the latest published version in {version_code}/delta or so? I don't think there is a need for storing past deltas?
Yes. A delta is tied to two app versions: the one it's updating from and the one it's updating to. Thus, it would be unusable by clients with a different "from" version installed than the "from" version the delta targets.
Storing past deltas may be desirable because not every client can be expected to perform every update. If, say, 100 clients are on v1.0 of an app, 100 are on v2.0, and a new v3.0 update is pushed out, making a delta for only the v2.0 -> v3.0 update still leaves 100 clients performing an update from v1.0 -> v3.0 without a delta.
Maybe it could be a time-based approach? Like storing the deltas for the past week or more of updates to the latest version.
Problem
Accrescent's repository metadata format and organization was not designed for cacheability, internationalization, or atomicity. As a result, Accrescent has limited scalability, target audience, and robustness. These obstacles must be overcome for Accrescent to become a viable alternative to existing app stores with comparable features and a scalable foundation to build on.
Purpose and scope
This RFC aims to thoroughly define the Accrescent repository metadata format(s), directory tree structure, and caching strategies to maximize cacheability, internationalization support, and availability. This design will incorporate both current features of Accrescent's repository metadata and future features which are known to be desired. Undeveloped features need not be fully defined; however, the design must not create any obvious conflicts or challenges for implementing future features.
These proposed changes are being made public to gather feedback on design to ensure the system as implemented meets the needs of Accrescent and won't require significant changes to the repository organization for the foreseeable future. If you have any questions, suggestions, comments, or concerns, please make them in this issue thread.
The repository metadata should be representable exclusively via static files, so it is assumed that no dynamic server calls are required. The decision to use a static file structure for the repository is out-of-scope for this RFC.
Organization
This section describes the proposed organization at a high level.
Directory structure
Below is the proposed directory structure for the repository metadata.
File contents
This section describes the contents of each file in the above directory structure.
index.sjson: A (not quite) JSON file containing the index of the repository's apps along with critical security information.
version: A plain text file containing the version code of the latest published version for this app.
{app_id}/metadata.json: Contains non-version-specific app metadata shown in the UI but not used by the installer.
listing.json: A localized store listing.
icon.png: A 512x512 square PNG app icon to be displayed in the store listing.
compat.json: App information used to determine compatability with the current device.
<uses-feature>
manifest elements.{version_code}/metadata.json: Contains version-specific app metadata shown in the UI but not used by the installer.
base.apk: The base APK for this app.
*.apk: All split APKs for this app.
Caching strategies
The below caching strategies apply both to the Accrescent client and caching proxies.
Usage diagrams
Known issues
Unresolved questions
Below are some unresolved questions about how certain metadata should be represented. They don't all need to be addressed before adopting a new metadata organization, but should at least be considered and possibly addressed.