chiark / gitweb /
move update.signjar() to common so it can also be used in signindex
authorHans-Christoph Steiner <hans@eds.org>
Wed, 15 Mar 2017 20:23:44 +0000 (21:23 +0100)
committerHans-Christoph Steiner <hans@eds.org>
Fri, 17 Mar 2017 12:55:40 +0000 (13:55 +0100)
fdroidserver/common.py
fdroidserver/signindex.py
fdroidserver/update.py
tests/common.TestCase
tests/signindex/guardianproject.jar [new file with mode: 0644]
tests/signindex/testy.jar [new file with mode: 0644]

index 342677879e270e191e984447ae1b8f4e9a948c45..17ea4c2f0148dcd84c25b11e7dd7b59c4847a17d 100644 (file)
@@ -387,6 +387,29 @@ def write_password_file(pwtype, password=None):
     config[pwtype + 'file'] = filename
 
 
+def signjar(jar):
+    '''
+    sign a JAR file with Java's jarsigner.
+
+    This does use old hashing algorithms, i.e. SHA1, but that's not
+    broken yet for file verification.  This could be set to SHA256,
+    but then Android < 4.3 would not be able to verify it.
+    https://code.google.com/p/android/issues/detail?id=38321
+    '''
+    args = [config['jarsigner'], '-keystore', config['keystore'],
+            '-storepass:file', config['keystorepassfile'],
+            '-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
+            jar, config['repo_keyalias']]
+    if config['keystore'] == 'NONE':
+        args += config['smartcardoptions']
+    else:  # smardcards never use -keypass
+        args += ['-keypass:file', config['keypassfile']]
+    p = FDroidPopen(args)
+    if p.returncode != 0:
+        logging.critical("Failed to sign %s!" % jar)
+        sys.exit(1)
+
+
 def get_local_metadata_files():
     '''get any metadata files local to an app's source repo
 
index caf9adb318599f4d4e2dce114aef8c84d117375a..658d4cb8fedf2cbf1b45a44a58d14731df668d5a 100644 (file)
@@ -22,7 +22,6 @@ from argparse import ArgumentParser
 import logging
 
 from . import common
-from .common import FDroidPopen
 
 config = None
 options = None
@@ -56,18 +55,7 @@ def main():
         unsigned = os.path.join(output_dir, 'index_unsigned.jar')
         if os.path.exists(unsigned):
 
-            args = [config['jarsigner'], '-keystore', config['keystore'],
-                    '-storepass:file', config['keystorepassfile'],
-                    '-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
-                    unsigned, config['repo_keyalias']]
-            if config['keystore'] == 'NONE':
-                args += config['smartcardoptions']
-            else:  # smardcards never use -keypass
-                args += ['-keypass:file', config['keypassfile']]
-            p = FDroidPopen(args)
-            if p.returncode != 0:
-                logging.critical("Failed to sign index")
-                sys.exit(1)
+            common.signjar(unsigned)
             os.rename(unsigned, os.path.join(output_dir, 'index.jar'))
             logging.info('Signed index in ' + output_dir)
             signed += 1
index 47cdd915914d63fcf7aa66656a9e9d03d9481602..19a1336804c5dd63ea4bc10d3bd974b25ffaa52a 100644 (file)
@@ -1287,7 +1287,7 @@ def make_index_v1(apps, packages, repodir, repodict, requestsdict):
     jar_file = os.path.join(repodir, 'index-v1.jar')
     with zipfile.ZipFile(jar_file, 'w', zipfile.ZIP_DEFLATED) as jar:
         jar.write(index_file, json_name)
-    signjar(jar_file)
+    common.signjar(jar_file)
     os.remove(index_file)
 
 
@@ -1540,7 +1540,7 @@ def make_index_v0(apps, apks, repodir, repodict, requestsdict):
             if os.path.exists(signed):
                 os.remove(signed)
         else:
-            signjar(signed)
+            common.signjar(signed)
 
     # Copy the repo icon into the repo directory...
     icon_dir = os.path.join(repodir, 'icons')
@@ -1548,29 +1548,6 @@ def make_index_v0(apps, apks, repodir, repodict, requestsdict):
     shutil.copyfile(config['repo_icon'], iconfilename)
 
 
-def signjar(jar):
-    '''
-    sign a JAR file with Java's jarsigner.
-
-    This does use old hashing algorithms, i.e. SHA1, but that's not
-    broken yet for file verification.  This could be set to SHA256,
-    but then Android < 4.3 would not be able to verify it.
-    https://code.google.com/p/android/issues/detail?id=38321
-    '''
-    args = [config['jarsigner'], '-keystore', config['keystore'],
-            '-storepass:file', config['keystorepassfile'],
-            '-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
-            jar, config['repo_keyalias']]
-    if config['keystore'] == 'NONE':
-        args += config['smartcardoptions']
-    else:  # smardcards never use -keypass
-        args += ['-keypass:file', config['keypassfile']]
-    p = FDroidPopen(args)
-    if p.returncode != 0:
-        logging.critical("Failed to sign index")
-        sys.exit(1)
-
-
 def make_categories_txt(repodir, categories):
     '''Write a category list in the repo to allow quick access'''
     catdata = ''
index 9e00904fc53ffa0ab08659dbadb743789fb80a71..98939985b0d60ca28fe0cc3881cc215f27fe1b7c 100755 (executable)
@@ -157,6 +157,26 @@ class CommonTest(unittest.TestCase):
         p = fdroidserver.common.FDroidPopen(commands, stderr_to_stdout=False)
         self.assertEqual(p.output, 'stdout message\n')
 
+    def test_signjar(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__)
+        tmpdir = os.path.join(basedir, '..', '.testfiles')
+        if not os.path.exists(tmpdir):
+            os.makedirs(tmpdir)
+        sourcedir = os.path.join(basedir, 'signindex')
+        testsdir = tempfile.mkdtemp(prefix='test_signjar', dir=tmpdir)
+        for f in ('testy.jar', 'guardianproject.jar',):
+            sourcefile = os.path.join(sourcedir, f)
+            testfile = os.path.join(testsdir, f)
+            shutil.copy(sourcefile, testsdir)
+            fdroidserver.common.signjar(testfile)
+            # these should be resigned, and therefore different
+            self.assertNotEqual(open(sourcefile, 'rb').read(), open(testfile, 'rb').read())
+
 
 if __name__ == "__main__":
     parser = optparse.OptionParser()
diff --git a/tests/signindex/guardianproject.jar b/tests/signindex/guardianproject.jar
new file mode 100644 (file)
index 0000000..946c69a
Binary files /dev/null and b/tests/signindex/guardianproject.jar differ
diff --git a/tests/signindex/testy.jar b/tests/signindex/testy.jar
new file mode 100644 (file)
index 0000000..6d7dd35
Binary files /dev/null and b/tests/signindex/testy.jar differ