Browse Source

fallback to minsdk when targetsdk isn't set

Androguard already has a function always returning an int here, so let's
use that.

Also put in a guard against minsdk not being set.
merge-requests/802/head
Marcus Hoffmann 2 months ago
parent
commit
7de601a5b5
4 changed files with 50 additions and 4 deletions
  1. +15
    -2
      fdroidserver/common.py
  2. +35
    -2
      tests/common.TestCase
  3. BIN
      tests/no_targetsdk_minsdk1_unsigned.apk
  4. BIN
      tests/no_targetsdk_minsdk30_unsigned.apk

+ 15
- 2
fdroidserver/common.py View File

@ -3047,6 +3047,19 @@ def apk_extract_signatures(apkpath, outdir, manifest=True):
out_file.write(in_apk.read(f.filename))
def get_min_sdk_version(apk):
"""
This wraps the androguard function to always return and int and fall back to 1
if we can't get a valid minsdk version
:param apk: androguard apk object
:return: minsdk as int
"""
try:
return int(apk.get_min_sdk_version())
except TypeError:
return 1
def sign_apk(unsigned_path, signed_path, keyalias):
"""Sign and zipalign an unsigned APK, then save to a new file, deleting the unsigned
@ -3068,7 +3081,7 @@ def sign_apk(unsigned_path, signed_path, keyalias):
"""
apk = _get_androguard_APK(unsigned_path)
if int(apk.get_target_sdk_version()) >= 30:
if apk.get_effective_target_sdk_version() >= 30:
if config['keystore'] == 'NONE':
# NOTE: apksigner doesn't like -providerName/--provider-name at all, don't use
# apksigner documents the options as --ks-provider-class and --ks-provider-arg
@ -3098,7 +3111,7 @@ def sign_apk(unsigned_path, signed_path, keyalias):
os.remove(unsigned_path)
else:
if int(apk.get_min_sdk_version()) < 18:
if get_min_sdk_version(apk) < 18:
signature_algorithm = ['-sigalg', 'SHA1withRSA', '-digestalg', 'SHA1']
else:
signature_algorithm = ['-sigalg', 'SHA256withRSA', '-digestalg', 'SHA-256']

+ 35
- 2
tests/common.TestCase View File

@ -697,6 +697,37 @@ class CommonTest(unittest.TestCase):
# verify it has a v2 signature
self.assertTrue(fdroidserver.common._get_androguard_APK(signed).is_signed_v2())
def test_sign_no_targetsdk(self):
fdroidserver.common.config = None
config = fdroidserver.common.read_config(fdroidserver.common.options)
if not fdroidserver.common.find_apksigner():
self.skipTest('SKIPPING as apksigner is not installed!')
config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner')
config['keyalias'] = 'sova'
config['keystorepass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI='
config['keypass'] = 'r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI='
config['keystore'] = os.path.join(self.basedir, 'keystore.jks')
testdir = tempfile.mkdtemp(prefix=inspect.currentframe().f_code.co_name, dir=self.tmpdir)
shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk30_unsigned.apk'), testdir)
unsigned = os.path.join(testdir, 'no_targetsdk_minsdk30_unsigned.apk')
signed = os.path.join(testdir, 'no_targetsdk_minsdk30_signed.apk')
fdroidserver.common.sign_apk(unsigned, signed, config['keyalias'])
self.assertTrue(fdroidserver.common.verify_apk_signature(signed))
self.assertTrue(fdroidserver.common._get_androguard_APK(signed).is_signed_v2())
shutil.copy(os.path.join(self.basedir, 'no_targetsdk_minsdk1_unsigned.apk'), testdir)
unsigned = os.path.join(testdir, 'no_targetsdk_minsdk1_unsigned.apk')
signed = os.path.join(testdir, 'no_targetsdk_minsdk1_signed.apk')
self.assertFalse(fdroidserver.common.verify_apk_signature(unsigned))
fdroidserver.common.sign_apk(unsigned, signed, config['keyalias'])
self.assertTrue(os.path.isfile(signed))
self.assertFalse(os.path.isfile(unsigned))
self.assertTrue(fdroidserver.common.verify_apk_signature(signed))
def test_get_apk_id(self):
config = dict()
fdroidserver.common.fill_config_defaults(config)
@ -796,11 +827,11 @@ class CommonTest(unittest.TestCase):
"""This is a sanity test that androguard isn't broken"""
def get_minSdkVersion(apkfile):
apk = fdroidserver.common._get_androguard_APK(apkfile)
return int(apk.get_min_sdk_version())
return fdroidserver.common.get_min_sdk_version(apk)
def get_targetSdkVersion(apkfile):
apk = fdroidserver.common._get_androguard_APK(apkfile)
return int(apk.get_target_sdk_version())
return apk.get_effective_target_sdk_version()
self.assertEqual(4, get_minSdkVersion('bad-unicode-πÇÇ现代通用字-български-عربي1.apk'))
self.assertEqual(14, get_minSdkVersion('org.bitbucket.tickytacky.mirrormirror_1.apk'))
@ -826,6 +857,8 @@ class CommonTest(unittest.TestCase):
self.assertEqual(4, get_minSdkVersion('repo/urzip-; Рахма́, [rɐxˈmanʲɪnəf] سيرجي_رخمانينوف 谢·.apk'))
self.assertEqual(30, get_targetSdkVersion('minimal_targetsdk_30_unsigned.apk'))
self.assertEqual(1, get_targetSdkVersion('no_targetsdk_minsdk1_unsigned.apk'))
self.assertEqual(30, get_targetSdkVersion('no_targetsdk_minsdk30_unsigned.apk'))
def test_apk_release_name(self):
appid, vercode, sigfp = fdroidserver.common.apk_parse_release_filename('com.serwylo.lexica_905.apk')

BIN
tests/no_targetsdk_minsdk1_unsigned.apk View File


BIN
tests/no_targetsdk_minsdk30_unsigned.apk View File


Loading…
Cancel
Save