Skip to content

Commit

Permalink
apk_operations: support full cert for v2+ APKs
Browse files Browse the repository at this point in the history
The apksigner tool added support for printing PEM-encoded certificates
in the Android T SDK. This updates apk_operations 'print-certs' command
to use the new apksigner option. This allows us to support v2+ signed
APKs, even if the APK was not v1-signed.

This also fixes a TypeError in the App Bundle code path.

Fixed: 1298280
Fixed: 1349482
Test: out/Default/bin/trichrome_webview_apk print-certs --full-cert
Test: out/Default/bin/system_webview_apk print-certs --full-cert
Test: out/Default/bin/monochrome_public_bundle print-certs --full-cert
Test: Also tested on both "signed" & "unsigned" official builds
Change-Id: I830f6c69d86106a00ab9cf240c26ed920f3c1a2a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3795225
Auto-Submit: Nate Fischer <ntfschr@chromium.org>
Commit-Queue: Nate Fischer <ntfschr@chromium.org>
Commit-Queue: Sam Maier <smaier@chromium.org>
Reviewed-by: Sam Maier <smaier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1030746}
  • Loading branch information
ntfschr-chromium authored and Chromium LUCI CQ committed Aug 2, 2022
1 parent 975c0b4 commit 174f8c0
Showing 1 changed file with 17 additions and 17 deletions.
34 changes: 17 additions & 17 deletions build/android/apk_operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -1648,6 +1648,8 @@ def _RegisterExtraArgs(self, group):

def Run(self):
keytool = os.path.join(_JAVA_HOME, 'bin', 'keytool')
pem_certificate_pattern = re.compile(
r'-+BEGIN CERTIFICATE-+([\r\n0-9A-Za-z+/=]+)-+END CERTIFICATE-+[\r\n]*')
if self.is_bundle:
# Bundles are not signed until converted to .apks. The wrapper scripts
# record which key will be used to sign though.
Expand All @@ -1667,14 +1669,14 @@ def Run(self):
if self.args.full_cert:
# Redirect stderr to hide a keytool warning about using non-standard
# keystore format.
full_output = subprocess.check_output(
cmd + ['-rfc'], stderr=subprocess.STDOUT)
pem_encoded_certificate = subprocess.check_output(
cmd + ['-rfc'], stderr=subprocess.STDOUT).decode()
else:

def run_apksigner(min_sdk_version):
cmd = [
build_tools.GetPath('apksigner'), 'verify', '--min-sdk-version',
str(min_sdk_version), '--print-certs', '--verbose',
str(min_sdk_version), '--print-certs-pem', '--verbose',
self.apk_helper.path
]
logging.warning('Running: %s', ' '.join(cmd))
Expand Down Expand Up @@ -1716,25 +1718,23 @@ def run_apksigner(min_sdk_version):
if not stdout:
raise RuntimeError('apksigner was not able to verify APK')

print(stdout)
# Separate what the '--print-certs' flag would output vs. the additional
# signature output included by '--print-certs-pem'. The additional PEM
# output is only printed when self.args.full_cert is specified.
verification_hash_info = pem_certificate_pattern.sub('', stdout)
print(verification_hash_info)
if self.args.full_cert:
if 'v1 scheme (JAR signing): true' not in stdout:
raise Exception(
'Cannot print full certificate because apk is not V1 signed.')
m = pem_certificate_pattern.search(stdout)
if not m:
raise Exception('apksigner did not print a certificate')
pem_encoded_certificate = m.group(0)

cmd = [keytool, '-printcert', '-jarfile', self.apk_helper.path, '-rfc']
# Redirect stderr to hide a keytool warning about using non-standard
# keystore format.
full_output = subprocess.check_output(cmd,
stderr=subprocess.STDOUT,
universal_newlines=True)

if self.args.full_cert:
m = re.search(
r'-+BEGIN CERTIFICATE-+([\r\n0-9A-Za-z+/=]+)-+END CERTIFICATE-+',
full_output, re.MULTILINE)
m = pem_certificate_pattern.search(pem_encoded_certificate)
if not m:
raise Exception('Unable to parse certificate:\n{}'.format(full_output))
raise Exception(
'Unable to parse certificate:\n{}'.format(pem_encoded_certificate))
signature = re.sub(r'[\r\n]+', '', m.group(1))
print()
print('Full Signature:')
Expand Down

0 comments on commit 174f8c0

Please sign in to comment.