Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9517e170 authored by Tao Bao's avatar Tao Bao Committed by android-build-merger
Browse files

Merge "releasetools: Clean up check_target_files_signatures.py." am: f6e8d46e am: d82b810a

am: 2cfd9b90

Change-Id: I990c7048432699f94bbe9396484f0340681516c1
parents 8bd6e70f 2cfd9b90
Loading
Loading
Loading
Loading
+63 −54
Original line number Original line Diff line number Diff line
@@ -39,8 +39,11 @@ Usage: check_target_file_signatures [flags] target_files


"""
"""


from __future__ import print_function

import logging
import logging
import os
import os
import os.path
import re
import re
import subprocess
import subprocess
import sys
import sys
@@ -49,7 +52,7 @@ import zipfile
import common
import common


if sys.hexversion < 0x02070000:
if sys.hexversion < 0x02070000:
  print >> sys.stderr, "Python 2.7 or newer is required."
  print("Python 2.7 or newer is required.", file=sys.stderr)
  sys.exit(1)
  sys.exit(1)




@@ -65,8 +68,10 @@ logger = logging.getLogger(__name__)
class MyZipInfo(zipfile.ZipInfo):
class MyZipInfo(zipfile.ZipInfo):
  def _decodeExtra(self):
  def _decodeExtra(self):
    pass
    pass

zipfile.ZipInfo = MyZipInfo
zipfile.ZipInfo = MyZipInfo



OPTIONS = common.OPTIONS
OPTIONS = common.OPTIONS


OPTIONS.text = False
OPTIONS.text = False
@@ -76,28 +81,34 @@ OPTIONS.local_cert_dirs = ("vendor", "build")
PROBLEMS = []
PROBLEMS = []
PROBLEM_PREFIX = []
PROBLEM_PREFIX = []



def AddProblem(msg):
def AddProblem(msg):
  PROBLEMS.append(" ".join(PROBLEM_PREFIX) + " " + msg)
  PROBLEMS.append(" ".join(PROBLEM_PREFIX) + " " + msg)


def Push(msg):
def Push(msg):
  PROBLEM_PREFIX.append(msg)
  PROBLEM_PREFIX.append(msg)


def Pop():
def Pop():
  PROBLEM_PREFIX.pop()
  PROBLEM_PREFIX.pop()




def Banner(msg):
def Banner(msg):
  print "-" * 70
  print("-" * 70)
  print "  ", msg
  print("  ", msg)
  print "-" * 70
  print("-" * 70)




def GetCertSubject(cert):
def GetCertSubject(cert):
  p = common.Run(["openssl", "x509", "-inform", "DER", "-text"],
  p = common.Run(["openssl", "x509", "-inform", "DER", "-text"],
                 stdin=subprocess.PIPE,
                 stdin=subprocess.PIPE,
                 stdout=subprocess.PIPE)
                 stdout=subprocess.PIPE,
                 universal_newlines=False)
  out, err = p.communicate(cert)
  out, err = p.communicate(cert)
  if err and not err.strip():
  if err and not err.strip():
    return "(error reading cert subject)"
    return "(error reading cert subject)"
  for line in out.split("\n"):
  for line in out.decode().split("\n"):
    line = line.strip()
    line = line.strip()
    if line.startswith("Subject:"):
    if line.startswith("Subject:"):
      return line[8:].strip()
      return line[8:].strip()
@@ -105,6 +116,7 @@ def GetCertSubject(cert):




class CertDB(object):
class CertDB(object):

  def __init__(self):
  def __init__(self):
    self.certs = {}
    self.certs = {}


@@ -132,13 +144,13 @@ class CertDB(object):
          to_load.extend(certs)
          to_load.extend(certs)


    for i in to_load:
    for i in to_load:
      f = open(i)
      with open(i) as f:
        cert = common.ParseCertificate(f.read())
        cert = common.ParseCertificate(f.read())
      f.close()
      name, _ = os.path.splitext(i)
      name, _ = os.path.splitext(i)
      name, _ = os.path.splitext(name)
      name, _ = os.path.splitext(name)
      self.Add(cert, name)
      self.Add(cert, name)



ALL_CERTS = CertDB()
ALL_CERTS = CertDB()




@@ -152,13 +164,14 @@ def CertFromPKCS7(data, filename):
                    "-outform", "PEM",
                    "-outform", "PEM",
                    "-print_certs"],
                    "-print_certs"],
                   stdin=subprocess.PIPE,
                   stdin=subprocess.PIPE,
                   stdout=subprocess.PIPE)
                   stdout=subprocess.PIPE,
                   universal_newlines=False)
    out, err = p.communicate(data)
    out, err = p.communicate(data)
    if err and not err.strip():
    if err and not err.strip():
      AddProblem("error reading cert:\n" + err)
      AddProblem("error reading cert:\n" + err.decode())
      return None
      return None


    cert = common.ParseCertificate(out)
    cert = common.ParseCertificate(out.decode())
    if not cert:
    if not cert:
      AddProblem("error parsing cert output")
      AddProblem("error parsing cert output")
      return None
      return None
@@ -184,21 +197,19 @@ class APK(object):


  def RecordCerts(self, full_filename):
  def RecordCerts(self, full_filename):
    out = set()
    out = set()
    try:
    with zipfile.ZipFile(full_filename) as apk:
      f = open(full_filename)
      apk = zipfile.ZipFile(f, "r")
      pkcs7 = None
      pkcs7 = None
      for info in apk.infolist():
      for info in apk.infolist():
        if info.filename.startswith("META-INF/") and \
        filename = info.filename
           (info.filename.endswith(".DSA") or info.filename.endswith(".RSA")):
        if (filename.startswith("META-INF/") and
          pkcs7 = apk.read(info.filename)
            info.filename.endswith((".DSA", ".RSA"))):
          cert = CertFromPKCS7(pkcs7, info.filename)
          pkcs7 = apk.read(filename)
          cert = CertFromPKCS7(pkcs7, filename)
          out.add(cert)
          out.add(cert)
          ALL_CERTS.Add(cert)
          ALL_CERTS.Add(cert)
      if not pkcs7:
      if not pkcs7:
        AddProblem("no signature")
        AddProblem("no signature")
    finally:

      f.close()
    self.certs = frozenset(out)
    self.certs = frozenset(out)


  def ReadManifest(self, full_filename):
  def ReadManifest(self, full_filename):
@@ -247,8 +258,8 @@ class TargetFiles(object):
    # This is the list of wildcards of files we extract from |filename|.
    # This is the list of wildcards of files we extract from |filename|.
    apk_extensions = ['*.apk', '*.apex']
    apk_extensions = ['*.apk', '*.apex']


    self.certmap, compressed_extension = common.ReadApkCerts(
    with zipfile.ZipFile(filename) as input_zip:
        zipfile.ZipFile(filename))
      self.certmap, compressed_extension = common.ReadApkCerts(input_zip)
    if compressed_extension:
    if compressed_extension:
      apk_extensions.append('*.apk' + compressed_extension)
      apk_extensions.append('*.apk' + compressed_extension)


@@ -287,7 +298,7 @@ class TargetFiles(object):
    """Look for any instances where packages signed with different
    """Look for any instances where packages signed with different
    certs request the same sharedUserId."""
    certs request the same sharedUserId."""
    apks_by_uid = {}
    apks_by_uid = {}
    for apk in self.apks.itervalues():
    for apk in self.apks.values():
      if apk.shared_uid:
      if apk.shared_uid:
        apks_by_uid.setdefault(apk.shared_uid, []).append(apk)
        apks_by_uid.setdefault(apk.shared_uid, []).append(apk)


@@ -302,15 +313,15 @@ class TargetFiles(object):


      AddProblem("different cert sets for packages with uid %s" % (uid,))
      AddProblem("different cert sets for packages with uid %s" % (uid,))


      print "uid %s is shared by packages with different cert sets:" % (uid,)
      print("uid %s is shared by packages with different cert sets:" % (uid,))
      for apk in apks:
      for apk in apks:
        print "%-*s  [%s]" % (self.max_pkg_len, apk.package, apk.filename)
        print("%-*s  [%s]" % (self.max_pkg_len, apk.package, apk.filename))
        for cert in apk.certs:
        for cert in apk.certs:
          print "   ", ALL_CERTS.Get(cert)
          print("   ", ALL_CERTS.Get(cert))
      print
      print()


  def CheckExternalSignatures(self):
  def CheckExternalSignatures(self):
    for apk_filename, certname in self.certmap.iteritems():
    for apk_filename, certname in self.certmap.items():
      if certname == "EXTERNAL":
      if certname == "EXTERNAL":
        # Apps marked EXTERNAL should be signed with the test key
        # Apps marked EXTERNAL should be signed with the test key
        # during development, then manually re-signed after
        # during development, then manually re-signed after
@@ -326,25 +337,25 @@ class TargetFiles(object):
  def PrintCerts(self):
  def PrintCerts(self):
    """Display a table of packages grouped by cert."""
    """Display a table of packages grouped by cert."""
    by_cert = {}
    by_cert = {}
    for apk in self.apks.itervalues():
    for apk in self.apks.values():
      for cert in apk.certs:
      for cert in apk.certs:
        by_cert.setdefault(cert, []).append((apk.package, apk))
        by_cert.setdefault(cert, []).append((apk.package, apk))


    order = [(-len(v), k) for (k, v) in by_cert.iteritems()]
    order = [(-len(v), k) for (k, v) in by_cert.items()]
    order.sort()
    order.sort()


    for _, cert in order:
    for _, cert in order:
      print "%s:" % (ALL_CERTS.Get(cert),)
      print("%s:" % (ALL_CERTS.Get(cert),))
      apks = by_cert[cert]
      apks = by_cert[cert]
      apks.sort()
      apks.sort()
      for _, apk in apks:
      for _, apk in apks:
        if apk.shared_uid:
        if apk.shared_uid:
          print "  %-*s  %-*s  [%s]" % (self.max_fn_len, apk.filename,
          print("  %-*s  %-*s  [%s]" % (self.max_fn_len, apk.filename,
                                        self.max_pkg_len, apk.package,
                                        self.max_pkg_len, apk.package,
                                        apk.shared_uid)
                                        apk.shared_uid))
        else:
        else:
          print "  %-*s  %s" % (self.max_fn_len, apk.filename, apk.package)
          print("  %-*s  %s" % (self.max_fn_len, apk.filename, apk.package))
      print
      print()


  def CompareWith(self, other):
  def CompareWith(self, other):
    """Look for instances where a given package that exists in both
    """Look for instances where a given package that exists in both
@@ -365,12 +376,12 @@ class TargetFiles(object):
            by_certpair.setdefault((other.apks[i].certs,
            by_certpair.setdefault((other.apks[i].certs,
                                    self.apks[i].certs), []).append(i)
                                    self.apks[i].certs), []).append(i)
        else:
        else:
          print "%s [%s]: new APK (not in comparison target_files)" % (
          print("%s [%s]: new APK (not in comparison target_files)" % (
              i, self.apks[i].filename)
              i, self.apks[i].filename))
      else:
      else:
        if i in other.apks:
        if i in other.apks:
          print "%s [%s]: removed APK (only in comparison target_files)" % (
          print("%s [%s]: removed APK (only in comparison target_files)" % (
              i, other.apks[i].filename)
              i, other.apks[i].filename))


    if by_certpair:
    if by_certpair:
      AddProblem("some APKs changed certs")
      AddProblem("some APKs changed certs")
@@ -378,23 +389,23 @@ class TargetFiles(object):
      for (old, new), packages in sorted(by_certpair.items()):
      for (old, new), packages in sorted(by_certpair.items()):
        for i, o in enumerate(old):
        for i, o in enumerate(old):
          if i == 0:
          if i == 0:
            print "was", ALL_CERTS.Get(o)
            print("was", ALL_CERTS.Get(o))
          else:
          else:
            print "   ", ALL_CERTS.Get(o)
            print("   ", ALL_CERTS.Get(o))
        for i, n in enumerate(new):
        for i, n in enumerate(new):
          if i == 0:
          if i == 0:
            print "now", ALL_CERTS.Get(n)
            print("now", ALL_CERTS.Get(n))
          else:
          else:
            print "   ", ALL_CERTS.Get(n)
            print("   ", ALL_CERTS.Get(n))
        for i in sorted(packages):
        for i in sorted(packages):
          old_fn = other.apks[i].filename
          old_fn = other.apks[i].filename
          new_fn = self.apks[i].filename
          new_fn = self.apks[i].filename
          if old_fn == new_fn:
          if old_fn == new_fn:
            print "  %-*s  [%s]" % (max_pkg_len, i, old_fn)
            print("  %-*s  [%s]" % (max_pkg_len, i, old_fn))
          else:
          else:
            print "  %-*s  [was: %s; now: %s]" % (max_pkg_len, i,
            print("  %-*s  [was: %s; now: %s]" % (max_pkg_len, i,
                                                  old_fn, new_fn)
                                                  old_fn, new_fn))
        print
        print()




def main(argv):
def main(argv):
@@ -451,9 +462,9 @@ def main(argv):
    target_files.CompareWith(compare_files)
    target_files.CompareWith(compare_files)


  if PROBLEMS:
  if PROBLEMS:
    print "%d problem(s) found:\n" % (len(PROBLEMS),)
    print("%d problem(s) found:\n" % (len(PROBLEMS),))
    for p in PROBLEMS:
    for p in PROBLEMS:
      print p
      print(p)
    return 1
    return 1


  return 0
  return 0
@@ -464,9 +475,7 @@ if __name__ == '__main__':
    r = main(sys.argv[1:])
    r = main(sys.argv[1:])
    sys.exit(r)
    sys.exit(r)
  except common.ExternalError as e:
  except common.ExternalError as e:
    print
    print("\n   ERROR: %s\n" % (e,))
    print "   ERROR: %s" % (e,)
    print
    sys.exit(1)
    sys.exit(1)
  finally:
  finally:
    common.Cleanup()
    common.Cleanup()