Merge "allow APKs to be signed with multiple certs" into ics-factoryrom

This commit is contained in:
Doug Zongker
2011-09-29 14:08:06 -07:00
committed by Android (Google) Code Review

View File

@@ -187,7 +187,7 @@ def CertFromPKCS7(data, filename):
class APK(object): class APK(object):
def __init__(self, full_filename, filename): def __init__(self, full_filename, filename):
self.filename = filename self.filename = filename
self.cert = None self.certs = set()
Push(filename+":") Push(filename+":")
try: try:
self.RecordCert(full_filename) self.RecordCert(full_filename)
@@ -203,11 +203,10 @@ class APK(object):
for info in apk.infolist(): for info in apk.infolist():
if info.filename.startswith("META-INF/") and \ if info.filename.startswith("META-INF/") and \
(info.filename.endswith(".DSA") or info.filename.endswith(".RSA")): (info.filename.endswith(".DSA") or info.filename.endswith(".RSA")):
if pkcs7 is not None:
AddProblem("multiple certs")
pkcs7 = apk.read(info.filename) pkcs7 = apk.read(info.filename)
self.cert = CertFromPKCS7(pkcs7, info.filename) cert = CertFromPKCS7(pkcs7, info.filename)
ALL_CERTS.Add(self.cert) self.certs.add(cert)
ALL_CERTS.Add(cert)
if not pkcs7: if not pkcs7:
AddProblem("no signature") AddProblem("no signature")
finally: finally:
@@ -281,24 +280,19 @@ class TargetFiles(object):
for uid in sorted(apks_by_uid.keys()): for uid in sorted(apks_by_uid.keys()):
apks = apks_by_uid[uid] apks = apks_by_uid[uid]
for apk in apks[1:]: for apk in apks[1:]:
if apk.cert != apks[0].cert: if apk.certs != apks[0].certs:
break break
else: else:
# all the certs are the same; this uid is fine # all packages have the same set of certs; this uid is fine.
continue continue
AddProblem("uid %s shared across multiple certs" % (uid,)) AddProblem("different cert sets for packages with uid %s" % (uid,))
print "uid %s is shared by packages with different certs:" % (uid,) print "uid %s is shared by packages with different cert sets:" % (uid,)
x = [(i.cert, i.package, i) for i in apks] for apk in apks:
x.sort() print "%-*s [%s]" % (self.max_pkg_len, apk.package, apk.filename)
lastcert = None for cert in apk.certs:
for cert, _, apk in x: print " ", ALL_CERTS.Get(cert)
if cert != lastcert:
lastcert = cert
print " %s:" % (ALL_CERTS.Get(cert),)
print " %-*s [%s]" % (self.max_pkg_len,
apk.package, apk.filename)
print print
def CheckExternalSignatures(self): def CheckExternalSignatures(self):
@@ -319,7 +313,8 @@ class TargetFiles(object):
"""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.itervalues():
by_cert.setdefault(apk.cert, []).append((apk.package, apk)) for cert in apk.certs:
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.iteritems()]
order.sort() order.sort()
@@ -352,10 +347,10 @@ class TargetFiles(object):
for i in all: for i in all:
if i in self.apks: if i in self.apks:
if i in other.apks: if i in other.apks:
# in both; should have the same cert # in both; should have at least one cert in common
if self.apks[i].cert != other.apks[i].cert: if not (self.apks[i].cert & other.apks[i].cert):
by_certpair.setdefault((other.apks[i].cert, by_certpair.setdefault((other.apks[i].certs,
self.apks[i].cert), []).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)
@@ -368,8 +363,16 @@ class TargetFiles(object):
AddProblem("some APKs changed certs") AddProblem("some APKs changed certs")
Banner("APK signing differences") Banner("APK signing differences")
for (old, new), packages in sorted(by_certpair.items()): for (old, new), packages in sorted(by_certpair.items()):
print "was", ALL_CERTS.Get(old) for i, o in enumerate(old):
print "now", ALL_CERTS.Get(new) if i == 0:
print "was", ALL_CERTS.Get(o)
else:
print " ", ALL_CERTS.Get(o)
for i, n in enumerate(new):
if i == 0:
print "now", ALL_CERTS.Get(n)
else:
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