1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2020 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19import sys 20import os 21import argparse 22import subprocess 23from utils import makedirs 24import shutil 25import zipfile 26 27 28def cmd_popen(cmd: str): 29 proc = subprocess.Popen(cmd) 30 proc.wait() 31 ret_code = proc.returncode 32 if ret_code != 0: 33 raise Exception("hap warning: {} failed, return code is {}".format( 34 cmd, ret_code)) 35 36 37def parse_args(): 38 parser = argparse.ArgumentParser() 39 parser.add_argument('--packing-tool-path', help='packing tool path ') 40 parser.add_argument('--mode', help='package mode') 41 parser.add_argument('--json-path', help='profile') 42 parser.add_argument('--resources-path', help='resources') 43 parser.add_argument('--assets-path', help='assets') 44 parser.add_argument('--lib-path', help='lib') 45 parser.add_argument('--shared-libs-path', help='shared-libs') 46 parser.add_argument('--ability-so-path', help='ability so') 47 parser.add_argument('--index-path', help='index') 48 parser.add_argument('--unsignhap-path', help='unsignhap path') 49 parser.add_argument('--force', help='force') 50 parser.add_argument('--signtool-path', help='sign tool path') 51 parser.add_argument('--signhap-path', help='sign hap path') 52 parser.add_argument('--privatekey', help='privatekey') 53 parser.add_argument('--sign-server', help='sign_server') 54 parser.add_argument('--sign-algo', help='sign algo') 55 parser.add_argument('--cert-profile', help='cert profile') 56 parser.add_argument('--jks-path', help='jks path') 57 parser.add_argument('--cert-path', help='cert path') 58 parser.add_argument('--sign-by-server', help='sign mode') 59 args = parser.parse_args() 60 61 return args 62 63 64def hap_packing(args): 65 if not args.packing_tool_path: 66 print('hap warning: packing tool path empty') 67 return 68 packing_cmd = ['java', '-jar', args.packing_tool_path] 69 cmd_dict = { 70 '--mode': args.mode, 71 '--json-path': args.json_path, 72 '--resources-path': args.resources_path, 73 '--assets-path': args.assets_path, 74 '--lib-path': args.lib_path, 75 '--shared-libs-path': args.shared_libs_path, 76 '--ability-so-path': args.ability_so_path, 77 '--index-path': args.index_path, 78 '--out-path': args.unsignhap_path, 79 '--force': args.force, 80 '--sign-by-server': args.sign_by_server 81 } 82 for key, value in cmd_dict.items(): 83 if value: 84 packing_cmd.extend([key, value]) 85 cmd_popen(packing_cmd) 86 87 88def hap_signing(args): 89 user_name = '' 90 password = '' 91 if not args.signtool_path: 92 print('hap warning: signing tool path empty') 93 return 94 95 # sign by server 96 if args.sign_by_server == "True": 97 if 'ONLINE_USERNAME' in os.environ: 98 user_name = os.environ.get('ONLINE_USERNAME') 99 else: 100 print('hap warning: Environment variable ONLINE_USERNAME and ' + 101 'ONLINE_PASSWD are needed for app signning. ' + 102 'Please export it in bash.') 103 return 104 if 'ONLINE_PASSWD' in os.environ: 105 password = os.environ.get('ONLINE_PASSWD') 106 else: 107 print('hap warning: Environment variable ONLINE_USERNAME and ' + 108 'ONLINE_PASSWD are needed for app signning. ' + 109 'Please export it in bash.') 110 return 111 signing_cmd = [ 112 'java', '-jar', args.signtool_path, 'sign', '-mode', 'remote', 113 '-profileSigned', '1' 114 ] 115 cmd_dict = { 116 '-privatekey': args.privatekey, 117 '-server': args.sign_server, 118 '-inputFile': args.unsignhap_path, 119 '-outputFile': args.signhap_path, 120 '-username': user_name, 121 '-password': password, 122 '-signAlg': args.sign_algo, 123 '-profile': args.cert_profile 124 } 125 # sign by software. 126 else: 127 signtool_path = args.signtool_path 128 #The default password of the key is 123456. 129 # You are advised to use a key and certificate management tool ( 130 # such as keytool) to change the default password. 131 # For details, see section "Application Signature Verification 132 # Development Guide" in the Security Subsystem Development Guide. 133 signing_cmd = [ 134 'java', '-jar', signtool_path, 'sign-app', '-mode', 'localsign', 135 '-profileSigned', '1', '-keystorePwd', '123456', 136 '-keyPwd', '123456', '-inForm', 'zip', '-signCode', '0' 137 ] 138 cmd_dict = { 139 '-keyAlias': args.privatekey, 140 '-inFile': args.unsignhap_path, 141 '-outFile': args.signhap_path, 142 '-signAlg': args.sign_algo, 143 '-profileFile': args.cert_profile, 144 '-keystoreFile': args.jks_path, 145 '-appCertFile': args.cert_path 146 } 147 for key, value in cmd_dict.items(): 148 if value: 149 signing_cmd.extend([key, value]) 150 cmd_popen(signing_cmd) 151 152 153def main(): 154 args = parse_args() 155 156 # Workaround: hap packing tools multi-thread contention issue. 157 makedirs(os.path.dirname(args.unsignhap_path), exist_ok=True) 158 159 hap_packing(args) 160 if os.path.exists(args.unsignhap_path): 161 hap_signing(args) 162 os.remove(args.unsignhap_path) 163 164 165if __name__ == '__main__': 166 sys.exit(main()) 167