chiark / gitweb /
signindex: support signing index-v1.jar
authorHans-Christoph Steiner <hans@eds.org>
Thu, 16 Mar 2017 17:51:43 +0000 (18:51 +0100)
committerHans-Christoph Steiner <hans@eds.org>
Fri, 17 Mar 2017 13:12:03 +0000 (14:12 +0100)
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.

fdroidserver/common.py
fdroidserver/signindex.py
fdroidserver/update.py
tests/run-tests

index 17ea4c2f0148dcd84c25b11e7dd7b59c4847a17d..85f7eac0e59d02d8a678c95e9d712f06f33d2dd0 100644 (file)
@@ -34,6 +34,7 @@ import logging
 import hashlib
 import socket
 import base64
+import zipfile
 import xml.etree.ElementTree as XMLElementTree
 
 from datetime import datetime
@@ -410,6 +411,24 @@ def signjar(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
 
index 658d4cb8fedf2cbf1b45a44a58d14731df668d5a..cbc19aa0078063d5dd5dd5862ed0350eed39c92d 100644 (file)
@@ -54,12 +54,19 @@ def main():
 
         unsigned = os.path.join(output_dir, 'index_unsigned.jar')
         if os.path.exists(unsigned):
-
             common.signjar(unsigned)
             os.rename(unsigned, os.path.join(output_dir, 'index.jar'))
             logging.info('Signed index in ' + output_dir)
             signed += 1
 
+        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)
+            os.remove(index_file)
+            logging.info('Signed ' + index_file)
+            signed += 1
+
     if signed == 0:
         logging.info("Nothing to do")
 
index 19a1336804c5dd63ea4bc10d3bd974b25ffaa52a..8638dd6cd85b3e1fa995a59cabebc543aff9a6ac 100644 (file)
@@ -1282,13 +1282,9 @@ def make_index_v1(apps, packages, repodir, repodict, requestsdict):
         json.dump(output, fp, default=_index_encoder_default)
 
     if options.nosign:
-        logging.debug('index-v1 must have a signature, signindex will overwrite it!')
-
-    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)
-    common.signjar(jar_file)
-    os.remove(index_file)
+        logging.debug('index-v1 must have a signature, use `fdroid signindex` to create it!')
+    else:
+        common.sign_index_v1(repodir, json_name)
 
 
 def make_index_v0(apps, apks, repodir, repodict, requestsdict):
index 8b91ed02de3b0f5b7eb981b34cc4457595591ed1..743cc766ba0ca20c6acd0604a7d627d7860a4863 100755 (executable)
@@ -113,6 +113,33 @@ echo_header "print fdroid version"
 $fdroid --version
 
 
+#------------------------------------------------------------------------------#
+echo_header 'run process when building and signing are on separate machines'
+
+REPOROOT=`create_test_dir`
+cd $REPOROOT
+cp $WORKSPACE/tests/keystore.jks $REPOROOT/
+$fdroid init --keystore keystore.jks --repo-keyalias=sova
+echo 'keystorepass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py
+echo 'keypass = "r9aquRHYoI8+dYz6jKrLntQ5/NJNASFBacJh7Jv2BlI="' >> config.py
+echo "accepted_formats = ['txt', 'yml']" >> config.py
+echo 'keydname = "CN=Birdman, OU=Cell, O=Alcatraz, L=Alcatraz, S=California, C=US"' >> config.py
+test -d archive || mkdir archive
+test -d metadata || mkdir metadata
+cp $WORKSPACE/tests/metadata/info.guardianproject.urzip.yml metadata/
+test -d repo || mkdir repo
+test -d unsigned || mkdir unsigned
+cp $WORKSPACE/tests/urzip-release-unsigned.apk unsigned/info.guardianproject.urzip_100.apk
+$fdroid publish --verbose
+$fdroid update --verbose --nosign
+$fdroid signindex --verbose
+test -e repo/index.xml
+test -e repo/index.jar
+test -e repo/index-v1.jar
+test -L urzip.apk
+grep -F '<application id=' repo/index.xml > /dev/null
+
+
 #------------------------------------------------------------------------------#
 echo_header "test UTF-8 metadata"