support v3.1 signer rotation in signature copying
The following discussion from !1825 (merged) should be addressed:
- @eighthave started a discussion: (+2 comments)
From @drizzt:
Yes, single signer for the fingerprint only, by deliberate parity with the rest of fdroidserver. The graft itself is already multi-signer / rotation-safe. Worth separating the two layers:
Block transplant -- already multi-signer + rotation-safe.
apksigcopier.do_extractreads the entireAPKSigningBlockas raw bytes (apksigcopier.py:768 extract_v2_sig), preserving every v2/v3 signer entry, theproof-of-rotationattribute, the SigningCertificateLineage, future block IDs, anything opaque.apk_implant_signaturesre-injects it byte-for-byte at publish time. So a v3.1-rotated APK with one v3.0 signer (old key, SDK<33) plus one v3.1 signer (new key, SDK>=33) plus its lineage attribute survives the graft byte-identical -- Android's verifier sees exactly what upstream signed, full rotation semantics intact.Fingerprint -- single-signer by existing convention. The new write site uses
common.get_first_signer_certificate(common.py:3501), the same helper thatsigner_fingerprint,apk_signer_fingerprint, publish, update, and index v1+v2 have used for years. Its docstring is explicit: "JAR and APK Signatures allow for multiple signers, though it is rarely used ... this method only fetches the first certificate, and errors out if there are more." It pickscerts_v3[0]->certs_v2[0]-> first v1 block file, and asserts all three agree. So this MR doesn't introduce a fresh single-signer assumption -- it inherits the canonical one. The F-Droid metadataSigner:field is also a single fingerprint.Concrete v3.1 status today. androguard 4.1.3 only recognises block IDs
0xf05368c0(v3) and0x7109871a(v2); v3.1 (0x1b93ad61) is not parsed. (Same for 3.4.0a1, which CI ships.) For a v3.1-rotated APK the helper returns the v3.0 signer cert -- the old key, which is the identity users coming from upstream already trust. The v3.1 (new key) block is still present in the transplantedAPKSigningBlock, so Android still rotates for SDK 33+. That's a defensible choice for a drop-in replacement, but the metadata schema can't currently express "this old key can rotate to this new one", and that's the work that has to happen before v3.1 is properly first-class.What real multi-signer / v3.1+ support entails, beyond the parser swap:
- sigdir layout: single
developer.der-> N certs (developer.0.der, lineage proof, ...) or a manifest- metadata schema:
Signer:(single fp) -> list + rotation policy (allowed predecessors, SDK ranges)- every consumer (
signer_fingerprint,apk_signer_fingerprint, publish, update, index v1+v2) needs to know which identity matches expectation under rotation- androguard bumped to a release that understands v3.1 (or a v3.1-aware fallback parser)
That's metadata-schema work, not graft work -- would prefer leaving it to a follow-up, as you suggest. This MR keeps the byte-level graft rotation-safe and the fingerprint single-identity per existing convention.