1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-08-17 03:40:11 +02:00

index: always use jarsigner for verifying JAR signatures

apksigner v0.7 (build-tools 26.0.1), Google made it require that the
AndroidManifest.xml was present in the archive before it verifies the
signature.  So this needs to stick with the jarsigner hack for JARs.
This commit is contained in:
Hans-Christoph Steiner 2017-09-19 15:07:19 +02:00
parent 535f2afe90
commit 5dcb48831f
4 changed files with 31 additions and 23 deletions

View File

@ -50,7 +50,7 @@ from distutils.util import strtobool
import fdroidserver.metadata import fdroidserver.metadata
from fdroidserver import _ from fdroidserver import _
from fdroidserver.exception import FDroidException, VCSException, BuildException from fdroidserver.exception import FDroidException, VCSException, BuildException, VerificationException
from .asynchronousfilereader import AsynchronousFileReader from .asynchronousfilereader import AsynchronousFileReader
@ -2077,24 +2077,41 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
return None return None
def verify_apk_signature(apk, jar=False): def verify_jar_signature(jar):
"""Verifies the signature of a given JAR file.
jarsigner is very shitty: unsigned JARs pass as "verified"! So
this has to turn on -strict then check for result 4, since this
does not expect the signature to be from a CA-signed certificate.
:raises: VerificationException() if the JAR's signature could not be verified
"""
if subprocess.call([config['jarsigner'], '-strict', '-verify', jar]) != 4:
raise VerificationException(_("The repository's index could not be verified."))
def verify_apk_signature(apk, min_sdk_version=None):
"""verify the signature on an APK """verify the signature on an APK
Try to use apksigner whenever possible since jarsigner is very Try to use apksigner whenever possible since jarsigner is very
shitty: unsigned APKs pass as "verified"! So this has to turn on shitty: unsigned APKs pass as "verified"! Warning, this does
-strict then check for result 4. not work on JARs with apksigner >= 0.7 (build-tools 26.0.1)
You can set :param: jar to True if you want to use this method
to verify jar signatures.
""" """
if set_command_in_config('apksigner'): if set_command_in_config('apksigner'):
args = [config['apksigner'], 'verify'] args = [config['apksigner'], 'verify']
if jar: if min_sdk_version:
args += ['--min-sdk-version=1'] args += ['--min-sdk-version=' + min_sdk_version]
return subprocess.call(args + [apk]) == 0 return subprocess.call(args + [apk]) == 0
else: else:
logging.warning("Using Java's jarsigner, not recommended for verifying APKs! Use apksigner") logging.warning("Using Java's jarsigner, not recommended for verifying APKs! Use apksigner")
return subprocess.call([config['jarsigner'], '-strict', '-verify', apk]) == 4 try:
verify_jar_signature(apk)
return True
except:
pass
return False
def verify_old_apk_signature(apk): def verify_old_apk_signature(apk):

View File

@ -632,7 +632,7 @@ def download_repo_index(url_str, etag=None, verify_fingerprint=True):
jar = zipfile.ZipFile(fp) jar = zipfile.ZipFile(fp)
# verify that the JAR signature is valid # verify that the JAR signature is valid
verify_jar_signature(fp.name) common.verify_jar_signature(fp.name)
# get public key and its fingerprint from JAR # get public key and its fingerprint from JAR
public_key, public_key_fingerprint = get_public_key_from_jar(jar) public_key, public_key_fingerprint = get_public_key_from_jar(jar)
@ -652,16 +652,6 @@ def download_repo_index(url_str, etag=None, verify_fingerprint=True):
return index, new_etag return index, new_etag
def verify_jar_signature(file):
"""
Verifies the signature of a given JAR file.
:raises: VerificationException() if the JAR's signature could not be verified
"""
if not common.verify_apk_signature(file, jar=True):
raise VerificationException(_("The repository's index could not be verified."))
def get_public_key_from_jar(jar): def get_public_key_from_jar(jar):
""" """
Get the public key and its fingerprint from a JAR file. Get the public key and its fingerprint from a JAR file.

View File

@ -39,14 +39,14 @@ class IndexTest(unittest.TestCase):
source_dir = os.path.join(basedir, 'signindex') source_dir = os.path.join(basedir, 'signindex')
for f in ('testy.jar', 'guardianproject.jar'): for f in ('testy.jar', 'guardianproject.jar'):
testfile = os.path.join(source_dir, f) testfile = os.path.join(source_dir, f)
fdroidserver.index.verify_jar_signature(testfile) fdroidserver.common.verify_jar_signature(testfile)
def test_verify_jar_signature_fails(self): def test_verify_jar_signature_fails(self):
basedir = os.path.dirname(__file__) basedir = os.path.dirname(__file__)
source_dir = os.path.join(basedir, 'signindex') source_dir = os.path.join(basedir, 'signindex')
testfile = os.path.join(source_dir, 'unsigned.jar') testfile = os.path.join(source_dir, 'unsigned.jar')
with self.assertRaises(fdroidserver.index.VerificationException): with self.assertRaises(fdroidserver.index.VerificationException):
fdroidserver.index.verify_jar_signature(testfile) fdroidserver.common.verify_jar_signature(testfile)
def test_get_public_key_from_jar_succeeds(self): def test_get_public_key_from_jar_succeeds(self):
basedir = os.path.dirname(__file__) basedir = os.path.dirname(__file__)

View File

@ -266,6 +266,7 @@ cp $WORKSPACE/tests/urzip.apk \
sed -i 's,archive_older = [0-9],archive_older = 3,' config.py sed -i 's,archive_older = [0-9],archive_older = 3,' config.py
$fdroid update --pretty --nosign $fdroid update --pretty --nosign
echo "This will fail when jarsigner allows MD5 for APK signatures"
test `grep '<package>' archive/index.xml | wc -l` -eq 5 test `grep '<package>' archive/index.xml | wc -l` -eq 5
test `grep '<package>' repo/index.xml | wc -l` -eq 7 test `grep '<package>' repo/index.xml | wc -l` -eq 7