from queue import Queue
from zipfile import ZipFile
+from pyasn1.codec.der import decoder, encoder
+from pyasn1_modules import rfc2315
+from pyasn1.error import PyAsn1Error
+
import fdroidserver.metadata
from .asynchronousfilereader import AsynchronousFileReader
return " ".join(ret)
+def get_certificate(certificate_file):
+ """
+ Extracts a certificate from the given file.
+ :param certificate_file: file bytes (as string) representing the certificate
+ :return: A binary representation of the certificate's public key, or None in case of error
+ """
+ content = decoder.decode(certificate_file, asn1Spec=rfc2315.ContentInfo())[0]
+ if content.getComponentByName('contentType') != rfc2315.signedData:
+ return None
+ content = decoder.decode(content.getComponentByName('content'),
+ asn1Spec=rfc2315.SignedData())[0]
+ try:
+ certificates = content.getComponentByName('certificates')
+ cert = certificates[0].getComponentByName('certificate')
+ except PyAsn1Error:
+ logging.error("Certificates not found.")
+ return None
+ return encoder.encode(cert)
+
+
def write_to_config(thisconfig, key, value=None, config_file=None):
'''write a key/value to the local config.py
from xml.dom.minidom import Document
import requests
-from pyasn1.codec.der import decoder, encoder
-from pyasn1_modules import rfc2315
from fdroidserver import metadata, signindex, common
from fdroidserver.common import FDroidPopen, FDroidPopenBytes
raise VerificationException("Found multiple signing certificates for repository.")
# extract public key from certificate
- public_key = get_public_key_from_certificate(jar.read(certs[0]))
+ public_key = common.get_certificate(jar.read(certs[0]))
public_key_fingerprint = common.get_cert_fingerprint(public_key).replace(' ', '')
return public_key, public_key_fingerprint
-
-
-def get_public_key_from_certificate(certificate_file):
- """
- Extracts a public key from the given certificate.
- :param certificate_file: file bytes (as string) representing the certificate
- :return: A binary representation of the certificate's public key
- """
- content = decoder.decode(certificate_file, asn1Spec=rfc2315.ContentInfo())[0]
- if content.getComponentByName('contentType') != rfc2315.signedData:
- raise VerificationException("Unexpected certificate format.")
- content = decoder.decode(content.getComponentByName('content'),
- asn1Spec=rfc2315.SignedData())[0]
- certificates = content.getComponentByName('certificates')
- cert = certificates[0].getComponentByName('certificate')
- return encoder.encode(cert)
from argparse import ArgumentParser
import collections
-from pyasn1.error import PyAsn1Error
-from pyasn1.codec.der import decoder, encoder
-from pyasn1_modules import rfc2315
from binascii import hexlify
from PIL import Image
from . import common
from . import index
from . import metadata
-from .common import FDroidPopen, SdkToolsPopen
+from .common import SdkToolsPopen
METADATA_VERSION = 18
if an error occurred.
"""
- cert = None
-
# verify the jar signature is correct
- args = [config['jarsigner'], '-verify', apkpath]
- p = FDroidPopen(args)
- if p.returncode != 0:
- logging.critical(apkpath + " has a bad signature!")
+ if not common.verify_apk_signature(apkpath):
return None
with zipfile.ZipFile(apkpath, 'r') as apk:
-
certs = [n for n in apk.namelist() if common.CERT_PATH_REGEX.match(n)]
if len(certs) < 1:
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:]
+ cert_encoded = common.get_certificate(cert)
return hashlib.md5(hexlify(cert_encoded)).hexdigest()