Loading core/build_id.mk +1 −1 Original line number Diff line number Diff line Loading @@ -18,4 +18,4 @@ # (like "CRB01"). It must be a single word, and is # capitalized by convention. BUILD_ID=RP1A.200717.001 BUILD_ID=RP1A.200718.001 core/clear_vars.mk +2 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ LOCAL_SOONG_EXPORT_PROGUARD_FLAGS := LOCAL_SOONG_HEADER_JAR := LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR := LOCAL_SOONG_LINK_TYPE := LOCAL_SOONG_LINT_REPORTS := LOCAL_SOONG_PROGUARD_DICT := LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE := LOCAL_SOONG_DEVICE_RRO_DIRS := Loading Loading @@ -341,6 +342,7 @@ LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH):= LOCAL_REQUIRED_MODULES_$(TARGET_ARCH):= LOCAL_SHARED_LIBRARIES_$(TARGET_ARCH):= LOCAL_SOONG_JNI_LIBS_$(TARGET_ARCH):= LOCAL_SOONG_JNI_LIBS_SYMBOLS:= LOCAL_SRC_FILES_EXCLUDE_$(TARGET_ARCH):= LOCAL_SRC_FILES_$(TARGET_ARCH):= LOCAL_STATIC_LIBRARIES_$(TARGET_ARCH):= Loading core/main.mk +8 −0 Original line number Diff line number Diff line Loading @@ -1508,6 +1508,14 @@ ifneq ($(TARGET_BUILD_APPS),) $(if $(ALL_MODULES.$(m).BUNDLE),$(ALL_MODULES.$(m).BUNDLE):$(m)-base.zip)) $(call dist-for-goals,apps_only, $(apps_only_bundle_files)) # Dist the lint reports if they exist. apps_only_lint_report_files := $(foreach m,$(unbundled_build_modules),\ $(foreach report,$(ALL_MODULES.$(m).LINT_REPORTS),\ $(report):$(m)-$(notdir $(report)))) .PHONY: lint-check lint-check: $(foreach f, $(apps_only_lint_report_files), $(call word-colon,1,$(f))) $(call dist-for-goals,lint-check, $(apps_only_lint_report_files)) # For uninstallable modules such as static Java library, we have to dist the built file, # as <module_name>.<suffix> apps_only_dist_built_files := $(foreach m,$(unbundled_build_modules),$(if $(ALL_MODULES.$(m).INSTALLED),,\ Loading core/soong_app_prebuilt.mk +10 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ # LOCAL_SOONG_RRO_DIRS # LOCAL_SOONG_JNI_LIBS_$(TARGET_ARCH) # LOCAL_SOONG_JNI_LIBS_$(TARGET_2ND_ARCH) # LOCAL_SOONG_JNI_LIBS_SYMBOLS ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK)) $(call pretty-error,soong_app_prebuilt.mk may only be used from Soong) Loading Loading @@ -118,6 +119,11 @@ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \ $(call create-suite-dependencies) endif # install symbol files of JNI libraries my_jni_lib_symbols_copy_files := $(foreach f,$(LOCAL_SOONG_JNI_LIBS_SYMBOLS),\ $(call word-colon,1,$(f)):$(patsubst $(PRODUCT_OUT)/%,$(TARGET_OUT_UNSTRIPPED)/%,$(call word-colon,2,$(f)))) $(LOCAL_BUILT_MODULE): $(call copy-many-files, $(my_jni_lib_symbols_copy_files)) # embedded JNI will already have been handled by soong my_embed_jni := my_prebuilt_jni_libs := Loading Loading @@ -170,6 +176,10 @@ ifdef LOCAL_SOONG_BUNDLE ALL_MODULES.$(LOCAL_MODULE).BUNDLE := $(LOCAL_SOONG_BUNDLE) endif ifdef LOCAL_SOONG_LINT_REPORTS ALL_MODULES.$(my_register_name).LINT_REPORTS := $(LOCAL_SOONG_LINT_REPORTS) endif ifndef LOCAL_IS_HOST_MODULE ifeq ($(LOCAL_SDK_VERSION),system_current) my_link_type := java:system Loading tools/releasetools/check_target_files_signatures.py +89 −36 Original line number Diff line number Diff line Loading @@ -120,19 +120,18 @@ class CertDB(object): def __init__(self): self.certs = {} def Add(self, cert, name=None): if cert in self.certs: def Add(self, cert_digest, subject, name=None): if cert_digest in self.certs: if name: self.certs[cert] = self.certs[cert] + "," + name self.certs[cert_digest] = self.certs[cert_digest] + "," + name else: if name is None: name = "unknown cert %s (%s)" % (common.sha1(cert).hexdigest()[:12], GetCertSubject(cert)) self.certs[cert] = name name = "unknown cert %s (%s)" % (cert_digest[:12], subject) self.certs[cert_digest] = name def Get(self, cert): """Return the name for a given cert.""" return self.certs.get(cert, None) def Get(self, cert_digest): """Return the name for a given cert digest.""" return self.certs.get(cert_digest, None) def FindLocalCerts(self): to_load = [] Loading @@ -148,7 +147,10 @@ class CertDB(object): cert = common.ParseCertificate(f.read()) name, _ = os.path.splitext(i) name, _ = os.path.splitext(name) self.Add(cert, name) cert_sha1 = common.sha1(cert).hexdigest() cert_subject = GetCertSubject(cert) self.Add(cert_sha1, cert_subject, name) ALL_CERTS = CertDB() Loading Loading @@ -184,7 +186,7 @@ class APK(object): def __init__(self, full_filename, filename): self.filename = filename self.certs = None self.cert_digests = frozenset() self.shared_uid = None self.package = None Loading @@ -195,22 +197,68 @@ class APK(object): finally: Pop() def RecordCerts(self, full_filename): out = set() def ReadCertsDeprecated(self, full_filename): print("reading certs in deprecated way for {}".format(full_filename)) cert_digests = set() with zipfile.ZipFile(full_filename) as apk: pkcs7 = None for info in apk.infolist(): filename = info.filename if (filename.startswith("META-INF/") and info.filename.endswith((".DSA", ".RSA"))): pkcs7 = apk.read(filename) cert = CertFromPKCS7(pkcs7, filename) out.add(cert) ALL_CERTS.Add(cert) if not pkcs7: AddProblem("no signature") if not cert: continue cert_sha1 = common.sha1(cert).hexdigest() cert_subject = GetCertSubject(cert) ALL_CERTS.Add(cert_sha1, cert_subject) cert_digests.add(cert_sha1) if not cert_digests: AddProblem("No signature found") return self.cert_digests = frozenset(cert_digests) def RecordCerts(self, full_filename): """Parse and save the signature of an apk file.""" # Dump the cert info with apksigner cmd = ["apksigner", "verify", "--print-certs", full_filename] p = common.Run(cmd, stdout=subprocess.PIPE) output, _ = p.communicate() if p.returncode != 0: self.ReadCertsDeprecated(full_filename) return self.certs = frozenset(out) # Sample output: # Signer #1 certificate DN: ... # Signer #1 certificate SHA-256 digest: ... # Signer #1 certificate SHA-1 digest: ... # ... certs_info = {} certificate_regex = re.compile(r"(Signer #[0-9]+) (certificate .*):(.*)") for line in output.splitlines(): m = certificate_regex.match(line) if not m: continue signer, key, val = m.group(1), m.group(2), m.group(3) if certs_info.get(signer): certs_info[signer].update({key.strip(): val.strip()}) else: certs_info.update({signer: {key.strip(): val.strip()}}) if not certs_info: AddProblem("Failed to parse cert info") return cert_digests = set() for signer, props in certs_info.items(): subject = props.get("certificate DN") digest = props.get("certificate SHA-1 digest") if not subject or not digest: AddProblem("Failed to parse cert subject or digest") return ALL_CERTS.Add(digest, subject) cert_digests.add(digest) self.cert_digests = frozenset(cert_digests) def ReadManifest(self, full_filename): p = common.Run(["aapt2", "dump", "xmltree", full_filename, "--file", Loading Loading @@ -316,8 +364,8 @@ class TargetFiles(object): print("uid %s is shared by packages with different cert sets:" % (uid,)) for apk in apks: print("%-*s [%s]" % (self.max_pkg_len, apk.package, apk.filename)) for cert in apk.certs: print(" ", ALL_CERTS.Get(cert)) for digest in apk.cert_digests: print(" ", ALL_CERTS.Get(digest)) print() def CheckExternalSignatures(self): Loading @@ -328,25 +376,30 @@ class TargetFiles(object): # predexopting. Consider it an error if this app is now # signed with any key that is present in our tree. apk = self.apks_by_basename[apk_filename] name = ALL_CERTS.Get(apk.cert) if not name.startswith("unknown "): signed_with_external = False for digest in apk.cert_digests: name = ALL_CERTS.Get(digest) if name and name.startswith("unknown "): signed_with_external = True if not signed_with_external: Push(apk.filename) AddProblem("hasn't been signed with EXTERNAL cert") Pop() def PrintCerts(self): """Display a table of packages grouped by cert.""" by_cert = {} by_digest = {} for apk in self.apks.values(): for cert in apk.certs: by_cert.setdefault(cert, []).append((apk.package, apk)) for digest in apk.cert_digests: by_digest.setdefault(digest, []).append((apk.package, apk)) order = [(-len(v), k) for (k, v) in by_cert.items()] order = [(-len(v), k) for (k, v) in by_digest.items()] order.sort() for _, cert in order: print("%s:" % (ALL_CERTS.Get(cert),)) apks = by_cert[cert] for _, digest in order: print("%s:" % (ALL_CERTS.Get(digest),)) apks = by_digest[digest] apks.sort() for _, apk in apks: if apk.shared_uid: Loading @@ -366,15 +419,15 @@ class TargetFiles(object): max_pkg_len = max(self.max_pkg_len, other.max_pkg_len) by_certpair = {} by_digestpair = {} for i in all_apks: if i in self.apks: if i in other.apks: # in both; should have same set of certs if self.apks[i].certs != other.apks[i].certs: by_certpair.setdefault((other.apks[i].certs, self.apks[i].certs), []).append(i) if self.apks[i].cert_digests != other.apks[i].cert_digests: by_digestpair.setdefault((other.apks[i].cert_digests, self.apks[i].cert_digests), []).append(i) else: print("%s [%s]: new APK (not in comparison target_files)" % ( i, self.apks[i].filename)) Loading @@ -383,10 +436,10 @@ class TargetFiles(object): print("%s [%s]: removed APK (only in comparison target_files)" % ( i, other.apks[i].filename)) if by_certpair: if by_digestpair: AddProblem("some APKs changed certs") Banner("APK signing differences") for (old, new), packages in sorted(by_certpair.items()): for (old, new), packages in sorted(by_digestpair.items()): for i, o in enumerate(old): if i == 0: print("was", ALL_CERTS.Get(o)) Loading Loading
core/build_id.mk +1 −1 Original line number Diff line number Diff line Loading @@ -18,4 +18,4 @@ # (like "CRB01"). It must be a single word, and is # capitalized by convention. BUILD_ID=RP1A.200717.001 BUILD_ID=RP1A.200718.001
core/clear_vars.mk +2 −0 Original line number Diff line number Diff line Loading @@ -273,6 +273,7 @@ LOCAL_SOONG_EXPORT_PROGUARD_FLAGS := LOCAL_SOONG_HEADER_JAR := LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR := LOCAL_SOONG_LINK_TYPE := LOCAL_SOONG_LINT_REPORTS := LOCAL_SOONG_PROGUARD_DICT := LOCAL_SOONG_RESOURCE_EXPORT_PACKAGE := LOCAL_SOONG_DEVICE_RRO_DIRS := Loading Loading @@ -341,6 +342,7 @@ LOCAL_PREBUILT_JNI_LIBS_$(TARGET_ARCH):= LOCAL_REQUIRED_MODULES_$(TARGET_ARCH):= LOCAL_SHARED_LIBRARIES_$(TARGET_ARCH):= LOCAL_SOONG_JNI_LIBS_$(TARGET_ARCH):= LOCAL_SOONG_JNI_LIBS_SYMBOLS:= LOCAL_SRC_FILES_EXCLUDE_$(TARGET_ARCH):= LOCAL_SRC_FILES_$(TARGET_ARCH):= LOCAL_STATIC_LIBRARIES_$(TARGET_ARCH):= Loading
core/main.mk +8 −0 Original line number Diff line number Diff line Loading @@ -1508,6 +1508,14 @@ ifneq ($(TARGET_BUILD_APPS),) $(if $(ALL_MODULES.$(m).BUNDLE),$(ALL_MODULES.$(m).BUNDLE):$(m)-base.zip)) $(call dist-for-goals,apps_only, $(apps_only_bundle_files)) # Dist the lint reports if they exist. apps_only_lint_report_files := $(foreach m,$(unbundled_build_modules),\ $(foreach report,$(ALL_MODULES.$(m).LINT_REPORTS),\ $(report):$(m)-$(notdir $(report)))) .PHONY: lint-check lint-check: $(foreach f, $(apps_only_lint_report_files), $(call word-colon,1,$(f))) $(call dist-for-goals,lint-check, $(apps_only_lint_report_files)) # For uninstallable modules such as static Java library, we have to dist the built file, # as <module_name>.<suffix> apps_only_dist_built_files := $(foreach m,$(unbundled_build_modules),$(if $(ALL_MODULES.$(m).INSTALLED),,\ Loading
core/soong_app_prebuilt.mk +10 −0 Original line number Diff line number Diff line Loading @@ -11,6 +11,7 @@ # LOCAL_SOONG_RRO_DIRS # LOCAL_SOONG_JNI_LIBS_$(TARGET_ARCH) # LOCAL_SOONG_JNI_LIBS_$(TARGET_2ND_ARCH) # LOCAL_SOONG_JNI_LIBS_SYMBOLS ifneq ($(LOCAL_MODULE_MAKEFILE),$(SOONG_ANDROID_MK)) $(call pretty-error,soong_app_prebuilt.mk may only be used from Soong) Loading Loading @@ -118,6 +119,11 @@ $(foreach suite, $(LOCAL_COMPATIBILITY_SUITE), \ $(call create-suite-dependencies) endif # install symbol files of JNI libraries my_jni_lib_symbols_copy_files := $(foreach f,$(LOCAL_SOONG_JNI_LIBS_SYMBOLS),\ $(call word-colon,1,$(f)):$(patsubst $(PRODUCT_OUT)/%,$(TARGET_OUT_UNSTRIPPED)/%,$(call word-colon,2,$(f)))) $(LOCAL_BUILT_MODULE): $(call copy-many-files, $(my_jni_lib_symbols_copy_files)) # embedded JNI will already have been handled by soong my_embed_jni := my_prebuilt_jni_libs := Loading Loading @@ -170,6 +176,10 @@ ifdef LOCAL_SOONG_BUNDLE ALL_MODULES.$(LOCAL_MODULE).BUNDLE := $(LOCAL_SOONG_BUNDLE) endif ifdef LOCAL_SOONG_LINT_REPORTS ALL_MODULES.$(my_register_name).LINT_REPORTS := $(LOCAL_SOONG_LINT_REPORTS) endif ifndef LOCAL_IS_HOST_MODULE ifeq ($(LOCAL_SDK_VERSION),system_current) my_link_type := java:system Loading
tools/releasetools/check_target_files_signatures.py +89 −36 Original line number Diff line number Diff line Loading @@ -120,19 +120,18 @@ class CertDB(object): def __init__(self): self.certs = {} def Add(self, cert, name=None): if cert in self.certs: def Add(self, cert_digest, subject, name=None): if cert_digest in self.certs: if name: self.certs[cert] = self.certs[cert] + "," + name self.certs[cert_digest] = self.certs[cert_digest] + "," + name else: if name is None: name = "unknown cert %s (%s)" % (common.sha1(cert).hexdigest()[:12], GetCertSubject(cert)) self.certs[cert] = name name = "unknown cert %s (%s)" % (cert_digest[:12], subject) self.certs[cert_digest] = name def Get(self, cert): """Return the name for a given cert.""" return self.certs.get(cert, None) def Get(self, cert_digest): """Return the name for a given cert digest.""" return self.certs.get(cert_digest, None) def FindLocalCerts(self): to_load = [] Loading @@ -148,7 +147,10 @@ class CertDB(object): cert = common.ParseCertificate(f.read()) name, _ = os.path.splitext(i) name, _ = os.path.splitext(name) self.Add(cert, name) cert_sha1 = common.sha1(cert).hexdigest() cert_subject = GetCertSubject(cert) self.Add(cert_sha1, cert_subject, name) ALL_CERTS = CertDB() Loading Loading @@ -184,7 +186,7 @@ class APK(object): def __init__(self, full_filename, filename): self.filename = filename self.certs = None self.cert_digests = frozenset() self.shared_uid = None self.package = None Loading @@ -195,22 +197,68 @@ class APK(object): finally: Pop() def RecordCerts(self, full_filename): out = set() def ReadCertsDeprecated(self, full_filename): print("reading certs in deprecated way for {}".format(full_filename)) cert_digests = set() with zipfile.ZipFile(full_filename) as apk: pkcs7 = None for info in apk.infolist(): filename = info.filename if (filename.startswith("META-INF/") and info.filename.endswith((".DSA", ".RSA"))): pkcs7 = apk.read(filename) cert = CertFromPKCS7(pkcs7, filename) out.add(cert) ALL_CERTS.Add(cert) if not pkcs7: AddProblem("no signature") if not cert: continue cert_sha1 = common.sha1(cert).hexdigest() cert_subject = GetCertSubject(cert) ALL_CERTS.Add(cert_sha1, cert_subject) cert_digests.add(cert_sha1) if not cert_digests: AddProblem("No signature found") return self.cert_digests = frozenset(cert_digests) def RecordCerts(self, full_filename): """Parse and save the signature of an apk file.""" # Dump the cert info with apksigner cmd = ["apksigner", "verify", "--print-certs", full_filename] p = common.Run(cmd, stdout=subprocess.PIPE) output, _ = p.communicate() if p.returncode != 0: self.ReadCertsDeprecated(full_filename) return self.certs = frozenset(out) # Sample output: # Signer #1 certificate DN: ... # Signer #1 certificate SHA-256 digest: ... # Signer #1 certificate SHA-1 digest: ... # ... certs_info = {} certificate_regex = re.compile(r"(Signer #[0-9]+) (certificate .*):(.*)") for line in output.splitlines(): m = certificate_regex.match(line) if not m: continue signer, key, val = m.group(1), m.group(2), m.group(3) if certs_info.get(signer): certs_info[signer].update({key.strip(): val.strip()}) else: certs_info.update({signer: {key.strip(): val.strip()}}) if not certs_info: AddProblem("Failed to parse cert info") return cert_digests = set() for signer, props in certs_info.items(): subject = props.get("certificate DN") digest = props.get("certificate SHA-1 digest") if not subject or not digest: AddProblem("Failed to parse cert subject or digest") return ALL_CERTS.Add(digest, subject) cert_digests.add(digest) self.cert_digests = frozenset(cert_digests) def ReadManifest(self, full_filename): p = common.Run(["aapt2", "dump", "xmltree", full_filename, "--file", Loading Loading @@ -316,8 +364,8 @@ class TargetFiles(object): print("uid %s is shared by packages with different cert sets:" % (uid,)) for apk in apks: print("%-*s [%s]" % (self.max_pkg_len, apk.package, apk.filename)) for cert in apk.certs: print(" ", ALL_CERTS.Get(cert)) for digest in apk.cert_digests: print(" ", ALL_CERTS.Get(digest)) print() def CheckExternalSignatures(self): Loading @@ -328,25 +376,30 @@ class TargetFiles(object): # predexopting. Consider it an error if this app is now # signed with any key that is present in our tree. apk = self.apks_by_basename[apk_filename] name = ALL_CERTS.Get(apk.cert) if not name.startswith("unknown "): signed_with_external = False for digest in apk.cert_digests: name = ALL_CERTS.Get(digest) if name and name.startswith("unknown "): signed_with_external = True if not signed_with_external: Push(apk.filename) AddProblem("hasn't been signed with EXTERNAL cert") Pop() def PrintCerts(self): """Display a table of packages grouped by cert.""" by_cert = {} by_digest = {} for apk in self.apks.values(): for cert in apk.certs: by_cert.setdefault(cert, []).append((apk.package, apk)) for digest in apk.cert_digests: by_digest.setdefault(digest, []).append((apk.package, apk)) order = [(-len(v), k) for (k, v) in by_cert.items()] order = [(-len(v), k) for (k, v) in by_digest.items()] order.sort() for _, cert in order: print("%s:" % (ALL_CERTS.Get(cert),)) apks = by_cert[cert] for _, digest in order: print("%s:" % (ALL_CERTS.Get(digest),)) apks = by_digest[digest] apks.sort() for _, apk in apks: if apk.shared_uid: Loading @@ -366,15 +419,15 @@ class TargetFiles(object): max_pkg_len = max(self.max_pkg_len, other.max_pkg_len) by_certpair = {} by_digestpair = {} for i in all_apks: if i in self.apks: if i in other.apks: # in both; should have same set of certs if self.apks[i].certs != other.apks[i].certs: by_certpair.setdefault((other.apks[i].certs, self.apks[i].certs), []).append(i) if self.apks[i].cert_digests != other.apks[i].cert_digests: by_digestpair.setdefault((other.apks[i].cert_digests, self.apks[i].cert_digests), []).append(i) else: print("%s [%s]: new APK (not in comparison target_files)" % ( i, self.apks[i].filename)) Loading @@ -383,10 +436,10 @@ class TargetFiles(object): print("%s [%s]: removed APK (only in comparison target_files)" % ( i, other.apks[i].filename)) if by_certpair: if by_digestpair: AddProblem("some APKs changed certs") Banner("APK signing differences") for (old, new), packages in sorted(by_certpair.items()): for (old, new), packages in sorted(by_digestpair.items()): for i, o in enumerate(old): if i == 0: print("was", ALL_CERTS.Get(o)) Loading