From eb753be249f01f711fea6da326352831e6dd61a1 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 8 Dec 2021 14:50:05 +0100 Subject: [PATCH] dist: Add support for automatically signing Android App Bundles --- direct/src/dist/commands.py | 8 ++++++++ direct/src/dist/installers.py | 28 +++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 935ffc2147..e067906973 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -1565,6 +1565,9 @@ class bdist_apps(setuptools.Command): self.installers = {} self.dist_dir = os.path.join(os.getcwd(), 'dist') self.skip_build = False + self.signing_certificate = None + self.signing_private_key = None + self.signing_passphrase = None self.installer_functions = {} self._current_platform = None for opt in self._build_apps_options(): @@ -1578,6 +1581,11 @@ class bdist_apps(setuptools.Command): for key, value in _parse_dict(self.installers).items() } + if self.signing_certificate: + assert self.signing_private_key, 'Missing signing_private_key' + self.signing_certificate = os.path.abspath(self.signing_certificate) + self.signing_private_key = os.path.abspath(self.signing_private_key) + tmp = self.DEFAULT_INSTALLER_FUNCS.copy() tmp.update(self.installer_functions) tmp.update({ diff --git a/direct/src/dist/installers.py b/direct/src/dist/installers.py index 2313cd573b..7ee45645ff 100644 --- a/direct/src/dist/installers.py +++ b/direct/src/dist/installers.py @@ -218,10 +218,12 @@ def create_aab(command, basename, build_dir): axml.parse_xml(fh.read()) # We use our own zip implementation, which can create the correct - # alignment needed by Android automatically. + # alignment and signature needed by Android automatically. + bundle_fn.unlink() + bundle = p3d.ZipArchive() - if not bundle.open_write(bundle_fn): - command.announce.error( + if not bundle.open_read_write(bundle_fn): + command.announce( f'\tUnable to open {bundle_fn} for writing', distutils.log.ERROR) return @@ -290,3 +292,23 @@ def create_aab(command, basename, build_dir): fn = p3d.Filename.from_os_specific(dirpath) / name if fn.is_regular_file(): bundle.add_subfile(f'base/{rel_dirpath}/{name}', fn, 9) + + # Finally, generate the manifest file / signature, if a signing certificate + # has been specified. + if command.signing_certificate: + password = command.signing_passphrase or '' + + if not password and 'ENCRYPTED' in open(command.signing_private_key).read(): + # It appears to be encrypted, and we don't have a passphrase, so we + # must request it on the command-line. + from getpass import getpass + password = getpass(f'Enter pass phrase for private key: ') + + if not bundle.add_jar_signature( + p3d.Filename.from_os_specific(command.signing_certificate), + p3d.Filename.from_os_specific(command.signing_private_key), + password): + command.announce( + f'\tFailed to sign {bundle_fn}.', distutils.log.ERROR) + + bundle.close()