1
0
mirror of https://gitlab.com/fdroid/fdroidserver.git synced 2024-07-07 09:50:07 +02:00

Replace getsig.java with a pure python implementation

Special thanks to deki for helping out with the certificate encodings:
https://gitlab.com/snippets/1842

fixes #5 https://gitlab.com/fdroid/fdroidserver/issues/5
This commit is contained in:
Daniel Martí 2014-08-29 22:53:55 -04:00 committed by Ciaran Gultnieks
parent c88eff9af7
commit 6e2d0a9e1e
5 changed files with 55 additions and 30 deletions

View File

@ -24,9 +24,6 @@ include examples/config.py
include examples/fdroid-icon.png include examples/fdroid-icon.png
include examples/makebs.config.py include examples/makebs.config.py
include examples/opensc-fdroid.cfg include examples/opensc-fdroid.cfg
include fdroidserver/getsig/run.sh
include fdroidserver/getsig/make.sh
include fdroidserver/getsig/getsig.java
include tests/run-tests include tests/run-tests
include tests/urzip.apk include tests/urzip.apk
include wp-fdroid/AndroidManifest.xml include wp-fdroid/AndroidManifest.xml

View File

@ -29,6 +29,11 @@ import pickle
from xml.dom.minidom import Document from xml.dom.minidom import Document
from optparse import OptionParser from optparse import OptionParser
import time import time
from pyasn1.error import PyAsn1Error
from pyasn1.codec.der import decoder, encoder
from pyasn1_modules import rfc2315
from hashlib import md5
from PIL import Image from PIL import Image
import logging import logging
@ -322,6 +327,52 @@ def resize_all_icons(repodirs):
resize_icon(iconpath, density) resize_icon(iconpath, density)
cert_path_regex = re.compile(r'^META-INF/.*\.RSA$')
def getsig(apkpath):
""" Get the signing certificate of an apk. To get the same md5 has that
Android gets, we encode the .RSA certificate in a specific format and pass
it hex-encoded to the md5 digest algorithm.
:param apkpath: path to the apk
:returns: A string containing the md5 of the signature of the apk or None
if an error occurred.
"""
cert = None
with zipfile.ZipFile(apkpath, 'r') as apk:
certs = [n for n in apk.namelist() if cert_path_regex.match(n)]
if len(certs) < 1:
logging.error("Found no signing certificates on %s" % apkpath)
return None
if len(certs) > 1:
logging.error("Found multiple signing certificates on %s" % apkpath)
return None
cert = apk.read(certs[0])
content = decoder.decode(cert, asn1Spec=rfc2315.ContentInfo())[0]
if content.getComponentByName('contentType') != rfc2315.signedData:
logging.error("Unexpected format.")
return None
content = decoder.decode(content.getComponentByName('content'),
asn1Spec=rfc2315.SignedData())[0]
try:
certificates = content.getComponentByName('certificates')
except PyAsn1Error:
logging.error("Certificates not found.")
return None
cert_encoded = encoder.encode(certificates)[4:]
return md5(cert_encoded.encode('hex')).hexdigest()
def scan_apks(apps, apkcache, repodir, knownapks): def scan_apks(apps, apkcache, repodir, knownapks):
"""Scan the apks in the given repo directory. """Scan the apks in the given repo directory.
@ -476,18 +527,8 @@ def scan_apks(apps, apkcache, repodir, knownapks):
sys.exit(1) sys.exit(1)
# Get the signature (or md5 of, to be precise)... # Get the signature (or md5 of, to be precise)...
getsig_dir = os.path.join(os.path.dirname(__file__), 'getsig') thisinfo['sig'] = getsig(os.path.join(os.getcwd(), apkfile))
if not os.path.exists(getsig_dir + "/getsig.class"): if not thisinfo['sig']:
logging.critical("getsig.class not found. To fix: cd '%s' && ./make.sh" % getsig_dir)
sys.exit(1)
p = FDroidPopen(['java', '-cp', os.path.join(os.path.dirname(__file__), 'getsig'),
'getsig', os.path.join(os.getcwd(), apkfile)])
thisinfo['sig'] = None
for line in p.output.splitlines():
if line.startswith('Result:'):
thisinfo['sig'] = line[7:].strip()
break
if p.returncode != 0 or not thisinfo['sig']:
logging.critical("Failed to get apk signature") logging.critical("Failed to get apk signature")
sys.exit(1) sys.exit(1)

View File

@ -38,11 +38,6 @@ fi
export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
#------------------------------------------------------------------------------#
# run local build
cd $WORKSPACE/fdroidserver/getsig
./make.sh
#------------------------------------------------------------------------------# #------------------------------------------------------------------------------#
# run local tests # run local tests

View File

@ -1,14 +1,8 @@
#!/usr/bin/env python2 #!/usr/bin/env python2
from setuptools import setup from setuptools import setup
import os
import subprocess
import sys import sys
if not os.path.exists('fdroidserver/getsig/getsig.class'):
subprocess.check_output('cd fdroidserver/getsig && javac getsig.java',
shell=True)
setup(name='fdroidserver', setup(name='fdroidserver',
version='0.2.1', version='0.2.1',
description='F-Droid Server Tools', description='F-Droid Server Tools',
@ -25,8 +19,6 @@ setup(name='fdroidserver',
'examples/makebs.config.py', 'examples/makebs.config.py',
'examples/opensc-fdroid.cfg', 'examples/opensc-fdroid.cfg',
'examples/fdroid-icon.png']), 'examples/fdroid-icon.png']),
('fdroidserver/getsig',
['fdroidserver/getsig/getsig.class']),
], ],
install_requires=[ install_requires=[
'mwclient', 'mwclient',
@ -34,6 +26,8 @@ setup(name='fdroidserver',
'Pillow', 'Pillow',
'python-magic', 'python-magic',
'apache-libcloud >= 0.14.1', 'apache-libcloud >= 0.14.1',
'pyasn1',
'pyasn1-modules',
], ],
classifiers=[ classifiers=[
'Development Status :: 3 - Alpha', 'Development Status :: 3 - Alpha',

View File

@ -101,8 +101,6 @@ $python setup.py sdist
REPOROOT=`create_test_dir` REPOROOT=`create_test_dir`
cd $REPOROOT cd $REPOROOT
tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1` tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1`
cd $REPOROOT/fdroidserver-*/fdroidserver/getsig
./make.sh
cd $REPOROOT cd $REPOROOT
./fdroidserver-*/fdroid init ./fdroidserver-*/fdroid init
copy_apks_into_repo $REPOROOT copy_apks_into_repo $REPOROOT