mirror of
https://github.com/f-droid/fdroidserver.git
synced 2025-11-13 10:40:29 +03:00
verify: ensure only a single signature is in compared APK
The ZIP format allows multiple entries with the exact same filename, and on top of that, it does not allow deleting or updating entries. To make the `fdroid verify` procedure failsafe, it needs to create a new temporary APK that is made up on the contents of the "unsigned APK" and the signature from the "signed APK". Since it would be possible to give a signed APK as in the unsigned one's position, `fdroid verify` was not able to update the signature since it was just adding the new signature to the end of the ZIP file. When reading a ZIP, the first entry is used.
This commit is contained in:
parent
3c9eeff7f3
commit
998b6245e9
2 changed files with 71 additions and 15 deletions
|
|
@ -10,6 +10,7 @@ import shutil
|
|||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
from zipfile import ZipFile
|
||||
|
||||
localmodule = os.path.realpath(
|
||||
os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..'))
|
||||
|
|
@ -177,6 +178,46 @@ class CommonTest(unittest.TestCase):
|
|||
# these should be resigned, and therefore different
|
||||
self.assertNotEqual(open(sourcefile, 'rb').read(), open(testfile, 'rb').read())
|
||||
|
||||
def test_verify_apks(self):
|
||||
fdroidserver.common.config = None
|
||||
config = fdroidserver.common.read_config(fdroidserver.common.options)
|
||||
config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner')
|
||||
fdroidserver.common.config = config
|
||||
|
||||
basedir = os.path.dirname(__file__)
|
||||
sourceapk = os.path.join(basedir, 'urzip.apk')
|
||||
|
||||
tmpdir = os.path.join(basedir, '..', '.testfiles')
|
||||
if not os.path.exists(tmpdir):
|
||||
os.makedirs(tmpdir)
|
||||
testdir = tempfile.mkdtemp(prefix='test_verify_apks', dir=tmpdir)
|
||||
print('testdir', testdir)
|
||||
|
||||
copyapk = os.path.join(testdir, 'urzip-copy.apk')
|
||||
shutil.copy(sourceapk, copyapk)
|
||||
self.assertTrue(fdroidserver.common.verify_apk_signature(copyapk))
|
||||
self.assertIsNone(fdroidserver.common.verify_apks(sourceapk, copyapk, tmpdir))
|
||||
|
||||
unsignedapk = os.path.join(testdir, 'urzip-unsigned.apk')
|
||||
with ZipFile(sourceapk, 'r') as apk:
|
||||
with ZipFile(unsignedapk, 'w') as testapk:
|
||||
for info in apk.infolist():
|
||||
if not info.filename.startswith('META-INF/'):
|
||||
testapk.writestr(info, apk.read(info.filename))
|
||||
self.assertIsNone(fdroidserver.common.verify_apks(sourceapk, unsignedapk, tmpdir))
|
||||
|
||||
twosigapk = os.path.join(testdir, 'urzip-twosig.apk')
|
||||
otherapk = ZipFile(os.path.join(basedir, 'urzip-release.apk'), 'r')
|
||||
with ZipFile(sourceapk, 'r') as apk:
|
||||
with ZipFile(twosigapk, 'w') as testapk:
|
||||
for info in apk.infolist():
|
||||
testapk.writestr(info, apk.read(info.filename))
|
||||
if info.filename.startswith('META-INF/'):
|
||||
testapk.writestr(info, otherapk.read(info.filename))
|
||||
otherapk.close()
|
||||
self.assertFalse(fdroidserver.common.verify_apk_signature(twosigapk))
|
||||
self.assertIsNone(fdroidserver.common.verify_apks(sourceapk, twosigapk, tmpdir))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = optparse.OptionParser()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue