From: Torsten Grote Date: Wed, 29 Mar 2017 15:11:40 +0000 (-0300) Subject: Move index signing methods into signindex.py X-Git-Tag: 0.8~89^2~2 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=9f765ed6f7dca39001ab1be823265589f4c8b96a;p=fdroidserver.git Move index signing methods into signindex.py --- diff --git a/fdroidserver/common.py b/fdroidserver/common.py index f670282e..c1111939 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -34,7 +34,6 @@ import logging import hashlib import socket import base64 -import zipfile import xml.etree.ElementTree as XMLElementTree from binascii import hexlify @@ -390,47 +389,6 @@ 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 sign_index_v1(repodir, json_name): - """ - sign index-v1.json to make index-v1.jar - - This is a bit different than index.jar: instead of their being index.xml - and index_unsigned.jar, the presense of index-v1.json means that there is - unsigned data. That file is then stuck into a jar and signed by the - signing process. index-v1.json is never published to the repo. It is - included in the binary transparency log, if that is enabled. - """ - name, ext = get_extension(json_name) - index_file = os.path.join(repodir, json_name) - jar_file = os.path.join(repodir, name + '.jar') - with zipfile.ZipFile(jar_file, 'w', zipfile.ZIP_DEFLATED) as jar: - jar.write(index_file, json_name) - signjar(jar_file) - - def get_local_metadata_files(): '''get any metadata files local to an app's source repo diff --git a/fdroidserver/signindex.py b/fdroidserver/signindex.py index cbc19aa0..4f0ac678 100644 --- a/fdroidserver/signindex.py +++ b/fdroidserver/signindex.py @@ -18,6 +18,7 @@ import sys import os +import zipfile from argparse import ArgumentParser import logging @@ -27,6 +28,49 @@ config = None options = None +def sign_jar(jar): + """ + Sign a JAR file with Java's jarsigner. + + This method requires a properly initialized config object. + + 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 = common.FDroidPopen(args) + if p.returncode != 0: + logging.critical("Failed to sign %s!" % jar) + sys.exit(1) + + +def sign_index_v1(repodir, json_name): + """ + Sign index-v1.json to make index-v1.jar + + This is a bit different than index.jar: instead of their being index.xml + and index_unsigned.jar, the presence of index-v1.json means that there is + unsigned data. That file is then stuck into a jar and signed by the + signing process. index-v1.json is never published to the repo. It is + included in the binary transparency log, if that is enabled. + """ + name, ext = common.get_extension(json_name) + index_file = os.path.join(repodir, json_name) + jar_file = os.path.join(repodir, name + '.jar') + with zipfile.ZipFile(jar_file, 'w', zipfile.ZIP_DEFLATED) as jar: + jar.write(index_file, json_name) + sign_jar(jar_file) + + def main(): global config, options @@ -54,7 +98,7 @@ def main(): unsigned = os.path.join(output_dir, 'index_unsigned.jar') if os.path.exists(unsigned): - common.signjar(unsigned) + sign_jar(unsigned) os.rename(unsigned, os.path.join(output_dir, 'index.jar')) logging.info('Signed index in ' + output_dir) signed += 1 @@ -62,7 +106,7 @@ def main(): json_name = 'index-v1.json' index_file = os.path.join(output_dir, json_name) if os.path.exists(index_file): - common.sign_index_v1(output_dir, json_name) + sign_index_v1(output_dir, json_name) os.remove(index_file) logging.info('Signed ' + index_file) signed += 1 diff --git a/fdroidserver/update.py b/fdroidserver/update.py index 096323dd..436edf1d 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -45,6 +45,7 @@ from binascii import hexlify, unhexlify from PIL import Image import logging +from . import signindex from . import common from . import metadata from .common import FDroidPopen, FDroidPopenBytes, SdkToolsPopen @@ -1374,7 +1375,8 @@ def make_index_v1(apps, packages, repodir, repodict, requestsdict): if options.nosign: logging.debug('index-v1 must have a signature, use `fdroid signindex` to create it!') else: - common.sign_index_v1(repodir, json_name) + signindex.config = config + signindex.sign_index_v1(repodir, json_name) def make_index_v0(apps, apks, repodir, repodict, requestsdict): @@ -1626,7 +1628,8 @@ def make_index_v0(apps, apks, repodir, repodict, requestsdict): if os.path.exists(signed): os.remove(signed) else: - common.signjar(signed) + signindex.config = config + signindex.sign_jar(signed) # Copy the repo icon into the repo directory... icon_dir = os.path.join(repodir, 'icons') diff --git a/tests/common.TestCase b/tests/common.TestCase index db0be6d0..50cbd320 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -12,6 +12,8 @@ import tempfile import unittest from zipfile import ZipFile +import fdroidserver.signindex + localmodule = os.path.realpath( os.path.join(os.path.dirname(inspect.getfile(inspect.currentframe())), '..')) print('localmodule: ' + localmodule) @@ -163,6 +165,7 @@ class CommonTest(unittest.TestCase): config = fdroidserver.common.read_config(fdroidserver.common.options) config['jarsigner'] = fdroidserver.common.find_sdk_tools_cmd('jarsigner') fdroidserver.common.config = config + fdroidserver.signindex.config = config basedir = os.path.dirname(__file__) tmpdir = os.path.join(basedir, '..', '.testfiles') @@ -174,7 +177,7 @@ class CommonTest(unittest.TestCase): sourcefile = os.path.join(sourcedir, f) testfile = os.path.join(testsdir, f) shutil.copy(sourcefile, testsdir) - fdroidserver.common.signjar(testfile) + fdroidserver.signindex.sign_jar(testfile) # these should be resigned, and therefore different self.assertNotEqual(open(sourcefile, 'rb').read(), open(testfile, 'rb').read())