mirror of
				https://github.com/f-droid/fdroidserver.git
				synced 2025-11-04 14:30:30 +03: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:
		
							parent
							
								
									c88eff9af7
								
							
						
					
					
						commit
						6e2d0a9e1e
					
				
					 5 changed files with 55 additions and 30 deletions
				
			
		| 
						 | 
				
			
			@ -24,9 +24,6 @@ include examples/config.py
 | 
			
		|||
include examples/fdroid-icon.png
 | 
			
		||||
include examples/makebs.config.py
 | 
			
		||||
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/urzip.apk
 | 
			
		||||
include wp-fdroid/AndroidManifest.xml
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,11 @@ import pickle
 | 
			
		|||
from xml.dom.minidom import Document
 | 
			
		||||
from optparse import OptionParser
 | 
			
		||||
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
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -322,6 +327,52 @@ def resize_all_icons(repodirs):
 | 
			
		|||
                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):
 | 
			
		||||
    """Scan the apks in the given repo directory.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -476,18 +527,8 @@ def scan_apks(apps, apkcache, repodir, knownapks):
 | 
			
		|||
                sys.exit(1)
 | 
			
		||||
 | 
			
		||||
            # Get the signature (or md5 of, to be precise)...
 | 
			
		||||
            getsig_dir = os.path.join(os.path.dirname(__file__), 'getsig')
 | 
			
		||||
            if not os.path.exists(getsig_dir + "/getsig.class"):
 | 
			
		||||
                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']:
 | 
			
		||||
            thisinfo['sig'] = getsig(os.path.join(os.getcwd(), apkfile))
 | 
			
		||||
            if not thisinfo['sig']:
 | 
			
		||||
                logging.critical("Failed to get apk signature")
 | 
			
		||||
                sys.exit(1)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,11 +38,6 @@ fi
 | 
			
		|||
 | 
			
		||||
export PATH=/usr/lib/jvm/java-7-openjdk-amd64/bin:$PATH
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------------#
 | 
			
		||||
# run local build
 | 
			
		||||
cd $WORKSPACE/fdroidserver/getsig
 | 
			
		||||
./make.sh
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#------------------------------------------------------------------------------#
 | 
			
		||||
# run local tests
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										10
									
								
								setup.py
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								setup.py
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,14 +1,8 @@
 | 
			
		|||
#!/usr/bin/env python2
 | 
			
		||||
 | 
			
		||||
from setuptools import setup
 | 
			
		||||
import os
 | 
			
		||||
import subprocess
 | 
			
		||||
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',
 | 
			
		||||
      version='0.2.1',
 | 
			
		||||
      description='F-Droid Server Tools',
 | 
			
		||||
| 
						 | 
				
			
			@ -25,8 +19,6 @@ setup(name='fdroidserver',
 | 
			
		|||
                  'examples/makebs.config.py',
 | 
			
		||||
                  'examples/opensc-fdroid.cfg',
 | 
			
		||||
                  'examples/fdroid-icon.png']),
 | 
			
		||||
          ('fdroidserver/getsig',
 | 
			
		||||
              ['fdroidserver/getsig/getsig.class']),
 | 
			
		||||
          ],
 | 
			
		||||
      install_requires=[
 | 
			
		||||
          'mwclient',
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +26,8 @@ setup(name='fdroidserver',
 | 
			
		|||
          'Pillow',
 | 
			
		||||
          'python-magic',
 | 
			
		||||
          'apache-libcloud >= 0.14.1',
 | 
			
		||||
          'pyasn1',
 | 
			
		||||
          'pyasn1-modules',
 | 
			
		||||
          ],
 | 
			
		||||
      classifiers=[
 | 
			
		||||
          'Development Status :: 3 - Alpha',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,8 +101,6 @@ $python setup.py sdist
 | 
			
		|||
REPOROOT=`create_test_dir`
 | 
			
		||||
cd $REPOROOT
 | 
			
		||||
tar xzf `ls -1 $WORKSPACE/dist/fdroidserver-*.tar.gz | sort -n | tail -1`
 | 
			
		||||
cd $REPOROOT/fdroidserver-*/fdroidserver/getsig
 | 
			
		||||
./make.sh
 | 
			
		||||
cd $REPOROOT
 | 
			
		||||
./fdroidserver-*/fdroid init
 | 
			
		||||
copy_apks_into_repo $REPOROOT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue