15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci
45f9996aaSopenharmony_ci#
55f9996aaSopenharmony_ci# Copyright (c) 2020 Huawei Device Co., Ltd.
65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
85f9996aaSopenharmony_ci# You may obtain a copy of the License at
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
115f9996aaSopenharmony_ci#
125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
165f9996aaSopenharmony_ci# limitations under the License.
175f9996aaSopenharmony_ci#
185f9996aaSopenharmony_ci
195f9996aaSopenharmony_ciimport sys
205f9996aaSopenharmony_ciimport os
215f9996aaSopenharmony_ciimport argparse
225f9996aaSopenharmony_ciimport subprocess
235f9996aaSopenharmony_cifrom utils import makedirs
245f9996aaSopenharmony_ciimport shutil
255f9996aaSopenharmony_ciimport zipfile
265f9996aaSopenharmony_ci
275f9996aaSopenharmony_ci
285f9996aaSopenharmony_cidef cmd_popen(cmd: str):
295f9996aaSopenharmony_ci    proc = subprocess.Popen(cmd)
305f9996aaSopenharmony_ci    proc.wait()
315f9996aaSopenharmony_ci    ret_code = proc.returncode
325f9996aaSopenharmony_ci    if ret_code != 0:
335f9996aaSopenharmony_ci        raise Exception("hap warning: {} failed, return code is {}".format(
345f9996aaSopenharmony_ci            cmd, ret_code))
355f9996aaSopenharmony_ci
365f9996aaSopenharmony_ci
375f9996aaSopenharmony_cidef parse_args():
385f9996aaSopenharmony_ci    parser = argparse.ArgumentParser()
395f9996aaSopenharmony_ci    parser.add_argument('--packing-tool-path', help='packing tool path ')
405f9996aaSopenharmony_ci    parser.add_argument('--mode', help='package mode')
415f9996aaSopenharmony_ci    parser.add_argument('--json-path', help='profile')
425f9996aaSopenharmony_ci    parser.add_argument('--resources-path', help='resources')
435f9996aaSopenharmony_ci    parser.add_argument('--assets-path', help='assets')
445f9996aaSopenharmony_ci    parser.add_argument('--lib-path', help='lib')
455f9996aaSopenharmony_ci    parser.add_argument('--shared-libs-path', help='shared-libs')
465f9996aaSopenharmony_ci    parser.add_argument('--ability-so-path', help='ability so')
475f9996aaSopenharmony_ci    parser.add_argument('--index-path', help='index')
485f9996aaSopenharmony_ci    parser.add_argument('--unsignhap-path', help='unsignhap path')
495f9996aaSopenharmony_ci    parser.add_argument('--force', help='force')
505f9996aaSopenharmony_ci    parser.add_argument('--signtool-path', help='sign tool path')
515f9996aaSopenharmony_ci    parser.add_argument('--signhap-path', help='sign hap path')
525f9996aaSopenharmony_ci    parser.add_argument('--privatekey', help='privatekey')
535f9996aaSopenharmony_ci    parser.add_argument('--sign-server', help='sign_server')
545f9996aaSopenharmony_ci    parser.add_argument('--sign-algo', help='sign algo')
555f9996aaSopenharmony_ci    parser.add_argument('--cert-profile', help='cert profile')
565f9996aaSopenharmony_ci    parser.add_argument('--jks-path', help='jks path')
575f9996aaSopenharmony_ci    parser.add_argument('--cert-path', help='cert path')
585f9996aaSopenharmony_ci    parser.add_argument('--sign-by-server', help='sign mode')
595f9996aaSopenharmony_ci    args = parser.parse_args()
605f9996aaSopenharmony_ci
615f9996aaSopenharmony_ci    return args
625f9996aaSopenharmony_ci
635f9996aaSopenharmony_ci
645f9996aaSopenharmony_cidef hap_packing(args):
655f9996aaSopenharmony_ci    if not args.packing_tool_path:
665f9996aaSopenharmony_ci        print('hap warning: packing tool path empty')
675f9996aaSopenharmony_ci        return
685f9996aaSopenharmony_ci    packing_cmd = ['java', '-jar', args.packing_tool_path]
695f9996aaSopenharmony_ci    cmd_dict = {
705f9996aaSopenharmony_ci        '--mode': args.mode,
715f9996aaSopenharmony_ci        '--json-path': args.json_path,
725f9996aaSopenharmony_ci        '--resources-path': args.resources_path,
735f9996aaSopenharmony_ci        '--assets-path': args.assets_path,
745f9996aaSopenharmony_ci        '--lib-path': args.lib_path,
755f9996aaSopenharmony_ci        '--shared-libs-path': args.shared_libs_path,
765f9996aaSopenharmony_ci        '--ability-so-path': args.ability_so_path,
775f9996aaSopenharmony_ci        '--index-path': args.index_path,
785f9996aaSopenharmony_ci        '--out-path': args.unsignhap_path,
795f9996aaSopenharmony_ci        '--force': args.force,
805f9996aaSopenharmony_ci        '--sign-by-server': args.sign_by_server
815f9996aaSopenharmony_ci    }
825f9996aaSopenharmony_ci    for key, value in cmd_dict.items():
835f9996aaSopenharmony_ci        if value:
845f9996aaSopenharmony_ci            packing_cmd.extend([key, value])
855f9996aaSopenharmony_ci    cmd_popen(packing_cmd)
865f9996aaSopenharmony_ci
875f9996aaSopenharmony_ci
885f9996aaSopenharmony_cidef hap_signing(args):
895f9996aaSopenharmony_ci    user_name = ''
905f9996aaSopenharmony_ci    password = ''
915f9996aaSopenharmony_ci    if not args.signtool_path:
925f9996aaSopenharmony_ci        print('hap warning: signing tool path empty')
935f9996aaSopenharmony_ci        return
945f9996aaSopenharmony_ci
955f9996aaSopenharmony_ci    # sign by server
965f9996aaSopenharmony_ci    if args.sign_by_server == "True":
975f9996aaSopenharmony_ci        if 'ONLINE_USERNAME' in os.environ:
985f9996aaSopenharmony_ci            user_name = os.environ.get('ONLINE_USERNAME')
995f9996aaSopenharmony_ci        else:
1005f9996aaSopenharmony_ci            print('hap warning: Environment variable ONLINE_USERNAME and ' +
1015f9996aaSopenharmony_ci                  'ONLINE_PASSWD are needed for app signning. ' +
1025f9996aaSopenharmony_ci                  'Please export it in bash.')
1035f9996aaSopenharmony_ci            return
1045f9996aaSopenharmony_ci        if 'ONLINE_PASSWD' in os.environ:
1055f9996aaSopenharmony_ci            password = os.environ.get('ONLINE_PASSWD')
1065f9996aaSopenharmony_ci        else:
1075f9996aaSopenharmony_ci            print('hap warning: Environment variable ONLINE_USERNAME and ' +
1085f9996aaSopenharmony_ci                  'ONLINE_PASSWD are needed for app signning. ' +
1095f9996aaSopenharmony_ci                  'Please export it in bash.')
1105f9996aaSopenharmony_ci            return
1115f9996aaSopenharmony_ci        signing_cmd = [
1125f9996aaSopenharmony_ci            'java', '-jar', args.signtool_path, 'sign', '-mode', 'remote',
1135f9996aaSopenharmony_ci            '-profileSigned', '1'
1145f9996aaSopenharmony_ci        ]
1155f9996aaSopenharmony_ci        cmd_dict = {
1165f9996aaSopenharmony_ci            '-privatekey': args.privatekey,
1175f9996aaSopenharmony_ci            '-server': args.sign_server,
1185f9996aaSopenharmony_ci            '-inputFile': args.unsignhap_path,
1195f9996aaSopenharmony_ci            '-outputFile': args.signhap_path,
1205f9996aaSopenharmony_ci            '-username': user_name,
1215f9996aaSopenharmony_ci            '-password': password,
1225f9996aaSopenharmony_ci            '-signAlg': args.sign_algo,
1235f9996aaSopenharmony_ci            '-profile': args.cert_profile
1245f9996aaSopenharmony_ci        }
1255f9996aaSopenharmony_ci    # sign by software.
1265f9996aaSopenharmony_ci    else:
1275f9996aaSopenharmony_ci        signtool_path = args.signtool_path
1285f9996aaSopenharmony_ci        #The default password of the key is 123456.
1295f9996aaSopenharmony_ci        # You are advised to use a key and certificate management tool (
1305f9996aaSopenharmony_ci        # such as keytool) to change the default password.
1315f9996aaSopenharmony_ci        # For details, see section "Application Signature Verification
1325f9996aaSopenharmony_ci        # Development Guide" in the Security Subsystem Development Guide.
1335f9996aaSopenharmony_ci        signing_cmd = [
1345f9996aaSopenharmony_ci            'java', '-jar', signtool_path, 'sign-app', '-mode', 'localsign',
1355f9996aaSopenharmony_ci            '-profileSigned', '1', '-keystorePwd', '123456',
1365f9996aaSopenharmony_ci            '-keyPwd', '123456', '-inForm', 'zip', '-signCode', '0'
1375f9996aaSopenharmony_ci        ]
1385f9996aaSopenharmony_ci        cmd_dict = {
1395f9996aaSopenharmony_ci            '-keyAlias': args.privatekey,
1405f9996aaSopenharmony_ci            '-inFile': args.unsignhap_path,
1415f9996aaSopenharmony_ci            '-outFile': args.signhap_path,
1425f9996aaSopenharmony_ci            '-signAlg': args.sign_algo,
1435f9996aaSopenharmony_ci            '-profileFile': args.cert_profile,
1445f9996aaSopenharmony_ci            '-keystoreFile': args.jks_path,
1455f9996aaSopenharmony_ci            '-appCertFile': args.cert_path
1465f9996aaSopenharmony_ci        }
1475f9996aaSopenharmony_ci    for key, value in cmd_dict.items():
1485f9996aaSopenharmony_ci        if value:
1495f9996aaSopenharmony_ci            signing_cmd.extend([key, value])
1505f9996aaSopenharmony_ci    cmd_popen(signing_cmd)
1515f9996aaSopenharmony_ci
1525f9996aaSopenharmony_ci
1535f9996aaSopenharmony_cidef main():
1545f9996aaSopenharmony_ci    args = parse_args()
1555f9996aaSopenharmony_ci
1565f9996aaSopenharmony_ci    # Workaround: hap packing tools multi-thread contention issue.
1575f9996aaSopenharmony_ci    makedirs(os.path.dirname(args.unsignhap_path), exist_ok=True)
1585f9996aaSopenharmony_ci
1595f9996aaSopenharmony_ci    hap_packing(args)
1605f9996aaSopenharmony_ci    if os.path.exists(args.unsignhap_path):
1615f9996aaSopenharmony_ci        hap_signing(args)
1625f9996aaSopenharmony_ci        os.remove(args.unsignhap_path)
1635f9996aaSopenharmony_ci
1645f9996aaSopenharmony_ci
1655f9996aaSopenharmony_ciif __name__ == '__main__':
1665f9996aaSopenharmony_ci    sys.exit(main())
167