chiark / gitweb /
Add function to verify apks via jarsigner
authorParménides GV <parmegv@sdf.org>
Sat, 31 Jan 2015 15:55:18 +0000 (15:55 +0000)
committerCiaran Gultnieks <ciaran@ciarang.com>
Sat, 31 Jan 2015 15:55:18 +0000 (15:55 +0000)
fdroidserver/common.py

index c1962f8d829ad8934ee744ebdde0406bfcc1f251..3b26338501cbbb77692b0c0dd4e66d963047fecf 100644 (file)
@@ -31,6 +31,7 @@ import threading
 import magic
 import logging
 from distutils.version import LooseVersion
+from zipfile import ZipFile
 
 import metadata
 
@@ -1894,6 +1895,29 @@ def place_srclib(root_dir, number, libpath):
             o.write('android.library.reference.%d=%s\n' % (number, relpath))
 
 
+def verify_apks(signed_apk, unsigned_apk, tmp_dir):
+    """Verify that two apks are the same
+
+    One of the inputs is signed, the other is unsigned. The signature metadata
+    is transferred from the signed to the unsigned apk, and then jarsigner is
+    used to verify that the signature from the signed apk is also varlid for
+    the unsigned one.
+    """
+    with ZipFile(signed_apk) as signed_apk_as_zip:
+        meta_inf_files = ['META-INF/MANIFEST.MF', 'META-INF/CERT.SF', 'META-INF/CERT.RSA']
+        signed_apk_as_zip.extractall(tmp_dir, meta_inf_files)
+    with ZipFile(unsigned_apk, mode='a') as unsigned_apk_as_zip:
+        for meta_inf_file in meta_inf_files:
+            unsigned_apk_as_zip.write(os.path.join(tmp_dir, meta_inf_file), arcname=meta_inf_file)
+
+    if subprocess.call(['jarsigner', '-verify', unsigned_apk]) != 0:
+        logging.info("...NOT verified - {0}".format(signed_apk))
+        compare_apks(signed_apk, unsigned_apk, tmp_dir)
+        return False
+    logging.info("...successfully verified")
+    return True
+
+
 def compare_apks(apk1, apk2, tmp_dir):
     """Compare two apks