diff --git a/fdroidserver/common.py b/fdroidserver/common.py index acca01dd..884fea4b 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -2041,6 +2041,26 @@ def verify_apk_signature(apk, jar=False): return subprocess.call([config['jarsigner'], '-strict', '-verify', apk]) == 4 +def verify_old_apk_signature(apk): + """verify the signature on an archived APK, supporting deprecated algorithms + + F-Droid aims to keep every single binary that it ever published. Therefore, + it needs to be able to verify APK signatures that include deprecated/removed + algorithms. For example, jarsigner treats an MD5 signature as unsigned. + + jarsigner passes unsigned APKs as "verified"! So this has to turn + on -strict then check for result 4. + + """ + + _java_security = os.path.join(os.getcwd(), '.java.security') + with open(_java_security, 'w') as fp: + fp.write('jdk.jar.disabledAlgorithms=MD2, RSA keySize < 1024') + + return subprocess.call([config['jarsigner'], '-J-Djava.security.properties=' + _java_security, + '-strict', '-verify', apk]) == 4 + + apk_badchars = re.compile('''[/ :;'"]''') diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 39ab7023..6ef9c126 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -1184,9 +1184,18 @@ def scan_apk(apkcache, apkfilename, repodir, knownapks, use_date_from_apk): apk['srcname'] = srcfilename apk['size'] = os.path.getsize(apkfile) - # verify the jar signature is correct + # verify the jar signature is correct, allow deprecated + # algorithms only if the APK is in the archive. if not common.verify_apk_signature(apkfile): - return True, None, False + if repodir == 'archive': + if common.verify_old_apk_signature(apkfile): + apk['antiFeatures'].add('KnownVuln') + else: + return True, None, False + else: + logging.warning('Archiving "' + apkfilename + '" with invalid signature!') + move_apk_between_sections('repo', 'archive', apk) + return True, None, False if has_known_vulnerability(apkfile): apk['antiFeatures'].add('KnownVuln')