chiark / gitweb /
use jarsigner and keytool from same JDK as is being set in JAVA7_HOME
authorHans-Christoph Steiner <hans@eds.org>
Thu, 11 Feb 2016 19:43:55 +0000 (20:43 +0100)
committerHans-Christoph Steiner <hans@eds.org>
Thu, 11 Feb 2016 20:17:23 +0000 (21:17 +0100)
Using the same JDK throughout should prevent weird bugs where a setup might
use Java8's jarsigner and Java7's keytool.  This also allows the user to
set java_paths and have jarsigner and keytool used from that specified JDK.

This incorporates almost all of the patch that is in the Debian package
that forces fdroidserver to use the default JDK on that Debian release.

closes #93 https://gitlab.com/fdroid/fdroidserver/issues/93

fdroidserver/common.py
fdroidserver/publish.py
fdroidserver/signindex.py
fdroidserver/update.py
tests/update.TestCase

index 3473c426929d42dbce4dd86ad2019ee325e12a15..c30d3b4e07ed7d6492a47351f1959d5e83b395be 100644 (file)
@@ -154,6 +154,14 @@ def fill_config_defaults(thisconfig):
                     else:
                         thisconfig['java_paths'][m.group(1)] = d
 
+    for java_version in ('7', '8', '9'):
+        java_home = thisconfig['java_paths'][java_version]
+        jarsigner = os.path.join(java_home, 'bin', 'jarsigner')
+        if os.path.exists(jarsigner):
+            thisconfig['jarsigner'] = jarsigner
+            thisconfig['keytool'] = os.path.join(java_home, 'bin', 'keytool')
+            break  # Java7 is preferred, so quit if found
+
     for k in ['ndk_paths', 'java_paths']:
         d = thisconfig[k]
         for k2 in d.copy():
@@ -1810,7 +1818,7 @@ def verify_apks(signed_apk, unsigned_apk, tmp_dir):
         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:
+    if subprocess.call([config['jarsigner'], '-verify', unsigned_apk]) != 0:
         logging.info("...NOT verified - {0}".format(signed_apk))
         return compare_apks(signed_apk, unsigned_apk, tmp_dir)
     logging.info("...successfully verified")
@@ -1912,7 +1920,7 @@ def genkeystore(localconfig):
 
     write_password_file("keystorepass", localconfig['keystorepass'])
     write_password_file("keypass", localconfig['keypass'])
-    p = FDroidPopen(['keytool', '-genkey',
+    p = FDroidPopen([config['keytool'], '-genkey',
                      '-keystore', localconfig['keystore'],
                      '-alias', localconfig['repo_keyalias'],
                      '-keyalg', 'RSA', '-keysize', '4096',
@@ -1926,7 +1934,7 @@ def genkeystore(localconfig):
         raise BuildException("Failed to generate key", p.output)
     os.chmod(localconfig['keystore'], 0o0600)
     # now show the lovely key that was just generated
-    p = FDroidPopen(['keytool', '-list', '-v',
+    p = FDroidPopen([config['keytool'], '-list', '-v',
                      '-keystore', localconfig['keystore'],
                      '-alias', localconfig['repo_keyalias'],
                      '-storepass:file', config['keystorepassfile']])
index 49aa69468e12864d60c992ec76815014aa0d8ef8..f0089d862e9f619d9c10390a055dd8ef1a8eecc1 100644 (file)
@@ -47,6 +47,10 @@ def main():
 
     config = common.read_config(options)
 
+    if not ('jarsigner' in config and 'keytool' in config):
+        logging.critical('Java JDK not found! Install in standard location or set java_paths!')
+        sys.exit(1)
+
     log_dir = 'logs'
     if not os.path.isdir(log_dir):
         logging.info("Creating log directory")
@@ -163,12 +167,12 @@ def main():
 
             # See if we already have a key for this application, and
             # if not generate one...
-            p = FDroidPopen(['keytool', '-list',
+            p = FDroidPopen([config['keytool'], '-list',
                              '-alias', keyalias, '-keystore', config['keystore'],
                              '-storepass:file', config['keystorepassfile']])
             if p.returncode != 0:
                 logging.info("Key does not exist - generating...")
-                p = FDroidPopen(['keytool', '-genkey',
+                p = FDroidPopen([config['keytool'], '-genkey',
                                  '-keystore', config['keystore'],
                                  '-alias', keyalias,
                                  '-keyalg', 'RSA', '-keysize', '2048',
@@ -181,7 +185,7 @@ def main():
                     raise BuildException("Failed to generate key")
 
             # Sign the application...
-            p = FDroidPopen(['jarsigner', '-keystore', config['keystore'],
+            p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
                              '-storepass:file', config['keystorepassfile'],
                              '-keypass:file', config['keypassfile'], '-sigalg',
                              'SHA1withRSA', '-digestalg', 'SHA1',
index 50a434557497203ac7ff217d6b4499393a8ba279..82f2216acf501a8cb791e4df03ae4c4100bcf9fe 100644 (file)
@@ -40,6 +40,10 @@ def main():
 
     config = common.read_config(options)
 
+    if not 'jarsigner' in config:
+        logging.critical('Java jarsigner not found! Install in standard location or set java_paths!')
+        sys.exit(1)
+
     repodirs = ['repo']
     if config['archive_older'] != 0:
         repodirs.append('archive')
@@ -53,7 +57,7 @@ def main():
         unsigned = os.path.join(output_dir, 'index_unsigned.jar')
         if os.path.exists(unsigned):
 
-            args = ['jarsigner', '-keystore', config['keystore'],
+            args = [config['jarsigner'], '-keystore', config['keystore'],
                     '-storepass:file', config['keystorepassfile'],
                     '-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
                     unsigned, config['repo_keyalias']]
index c9cd903141cb0acecddcb87399236f8f2f565085..6bbf0fae9686d2f3fd30b719b59e3400a3faaaea 100644 (file)
@@ -367,7 +367,7 @@ def getsig(apkpath):
     cert = None
 
     # verify the jar signature is correct
-    args = ['jarsigner', '-verify', apkpath]
+    args = [config['jarsigner'], '-verify', apkpath]
     p = FDroidPopen(args)
     if p.returncode != 0:
         logging.critical(apkpath + " has a bad signature!")
@@ -711,7 +711,7 @@ def extract_pubkey():
     if 'repo_pubkey' in config:
         pubkey = unhexlify(config['repo_pubkey'])
     else:
-        p = FDroidPopen(['keytool', '-exportcert',
+        p = FDroidPopen([config['keytool'], '-exportcert',
                          '-alias', config['repo_keyalias'],
                          '-keystore', config['keystore'],
                          '-storepass:file', config['keystorepassfile']]
@@ -970,7 +970,7 @@ def make_index(apps, sortedids, apks, repodir, archive, categories):
             if os.path.exists(signed):
                 os.remove(signed)
         else:
-            args = ['jarsigner', '-keystore', config['keystore'],
+            args = [config['jarsigner'], '-keystore', config['keystore'],
                     '-storepass:file', config['keystorepassfile'],
                     '-digestalg', 'SHA1', '-sigalg', 'SHA1withRSA',
                     signed, config['repo_keyalias']]
@@ -1118,6 +1118,10 @@ def main():
 
     config = common.read_config(options)
 
+    if not ('jarsigner' in config and 'keytool' in config):
+        logging.critical('Java JDK not found! Install in standard location or set java_paths!')
+        sys.exit(1)
+
     repodirs = ['repo']
     if config['archive_older'] != 0:
         repodirs.append('archive')
index aa342abaff67931ebcdbd79bff7b43dfbe5aea01..07f5765428104daa6061c708352e0fc10b181fd9 100755 (executable)
@@ -42,6 +42,10 @@ class UpdateTest(unittest.TestCase):
             return None
 
     def testGoodGetsig(self):
+        # config needed to use jarsigner and keytool
+        config = dict()
+        fdroidserver.common.fill_config_defaults(config)
+        fdroidserver.update.config = config
         apkfile = os.path.join(os.path.dirname(__file__), 'urzip.apk')
         sig = self.javagetsig(apkfile)
         self.assertIsNotNone(sig, "sig is None")
@@ -59,6 +63,10 @@ class UpdateTest(unittest.TestCase):
             self.assertTrue(False, 'TypeError!')
 
     def testBadGetsig(self):
+        # config needed to use jarsigner and keytool
+        config = dict()
+        fdroidserver.common.fill_config_defaults(config)
+        fdroidserver.update.config = config
         apkfile = os.path.join(os.path.dirname(__file__), 'urzip-badsig.apk')
         sig = self.javagetsig(apkfile)
         self.assertIsNone(sig, "sig should be None: " + str(sig))