140681896Sopenharmony_ci#!/usr/bin/env python3 240681896Sopenharmony_ci# -*- coding: utf-8 -*- 340681896Sopenharmony_ci 440681896Sopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd. 540681896Sopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 640681896Sopenharmony_ci# you may not use this file except in compliance with the License. 740681896Sopenharmony_ci# You may obtain a copy of the License at 840681896Sopenharmony_ci# 940681896Sopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 1040681896Sopenharmony_ci# 1140681896Sopenharmony_ci# Unless required by applicable law or agreed to in writing, software 1240681896Sopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 1340681896Sopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1440681896Sopenharmony_ci# See the License for the specific language governing permissions and 1540681896Sopenharmony_ci# limitations under the License. 1640681896Sopenharmony_ci 1740681896Sopenharmony_ci""" 1840681896Sopenharmony_ciThe tool for making module package. 1940681896Sopenharmony_ci 2040681896Sopenharmony_cipositional arguments: 2140681896Sopenharmony_ci target_package Target package file path. 2240681896Sopenharmony_ci update_package Update package file path. 2340681896Sopenharmony_ci -pn PACKAGE_NAME, --package_name PACKAGE_NAME 2440681896Sopenharmony_ci Module package name. 2540681896Sopenharmony_ci -pk PRIVATE_KEY, --private_key PRIVATE_KEY 2640681896Sopenharmony_ci Private key file path. 2740681896Sopenharmony_ci -sc SIGN_CERT, --sign_cert SIGN_CERT 2840681896Sopenharmony_ci Sign cert file path. 2940681896Sopenharmony_ci""" 3040681896Sopenharmony_ciimport os 3140681896Sopenharmony_ciimport sys 3240681896Sopenharmony_ciimport argparse 3340681896Sopenharmony_ciimport subprocess 3440681896Sopenharmony_ciimport hashlib 3540681896Sopenharmony_ciimport zipfile 3640681896Sopenharmony_ciimport io 3740681896Sopenharmony_ciimport struct 3840681896Sopenharmony_ciimport logging 3940681896Sopenharmony_ci 4040681896Sopenharmony_cifrom asn1crypto import cms 4140681896Sopenharmony_cifrom asn1crypto import pem 4240681896Sopenharmony_cifrom asn1crypto import util 4340681896Sopenharmony_cifrom asn1crypto import x509 4440681896Sopenharmony_cifrom cryptography.hazmat.backends import default_backend 4540681896Sopenharmony_cifrom cryptography.hazmat.primitives import serialization 4640681896Sopenharmony_cifrom cryptography.hazmat.primitives.asymmetric import padding 4740681896Sopenharmony_cifrom cryptography.hazmat.primitives import hashes 4840681896Sopenharmony_ci 4940681896Sopenharmony_ci 5040681896Sopenharmony_ci# 1000000: max number of function recursion depth 5140681896Sopenharmony_ciMAXIMUM_RECURSION_DEPTH = 1000000 5240681896Sopenharmony_cisys.setrecursionlimit(MAXIMUM_RECURSION_DEPTH) 5340681896Sopenharmony_ci 5440681896Sopenharmony_ciBLCOK_SIZE = 8192 5540681896Sopenharmony_ciFOOTER_LENGTH = 6 5640681896Sopenharmony_ciZIP_ECOD_LENGTH = 22 5740681896Sopenharmony_ciDIGEST_SHA256 = 672 5840681896Sopenharmony_ciSHA256_HASH_LEN = 32 5940681896Sopenharmony_ci 6040681896Sopenharmony_ciCONTENT_INFO_FORMAT = "<2H32s" 6140681896Sopenharmony_ci# the length of zip eocd comment 6240681896Sopenharmony_ciZIP_EOCD_COMMENT_LEN_FORMAT = "<H" 6340681896Sopenharmony_ci# signed package footer 6440681896Sopenharmony_ciSIGANTURE_FOOTER_FORMAT = "<3H" 6540681896Sopenharmony_ci 6640681896Sopenharmony_ciSIGN_TOOL_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'zipalign.jar') 6740681896Sopenharmony_ci 6840681896Sopenharmony_ci 6940681896Sopenharmony_cidef target_package_check(arg): 7040681896Sopenharmony_ci """ 7140681896Sopenharmony_ci Argument check, which is used to check whether the specified arg is a file path. 7240681896Sopenharmony_ci :param arg: the arg to check. 7340681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 7440681896Sopenharmony_ci """ 7540681896Sopenharmony_ci if not os.path.isdir(arg): 7640681896Sopenharmony_ci UPDATE_LOGGER.print_log( 7740681896Sopenharmony_ci "Target package error, path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 7840681896Sopenharmony_ci return False 7940681896Sopenharmony_ci return arg 8040681896Sopenharmony_ci 8140681896Sopenharmony_ci 8240681896Sopenharmony_cidef package_name_check(arg): 8340681896Sopenharmony_ci """ 8440681896Sopenharmony_ci Argument check, which is used to check whether the specified arg is none. 8540681896Sopenharmony_ci :param arg: the arg to check. 8640681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 8740681896Sopenharmony_ci """ 8840681896Sopenharmony_ci if arg is None: 8940681896Sopenharmony_ci UPDATE_LOGGER.print_log( 9040681896Sopenharmony_ci "Package name error: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 9140681896Sopenharmony_ci return False 9240681896Sopenharmony_ci return arg 9340681896Sopenharmony_ci 9440681896Sopenharmony_ci 9540681896Sopenharmony_cidef private_key_check(arg): 9640681896Sopenharmony_ci """ 9740681896Sopenharmony_ci Argument check, which is used to check whether 9840681896Sopenharmony_ci the specified arg is a private key. 9940681896Sopenharmony_ci :param arg: the arg to check. 10040681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 10140681896Sopenharmony_ci """ 10240681896Sopenharmony_ci if arg != "ON_SERVER" and not os.path.isfile(arg): 10340681896Sopenharmony_ci UPDATE_LOGGER.print_log( 10440681896Sopenharmony_ci "FileNotFoundError, path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 10540681896Sopenharmony_ci return False 10640681896Sopenharmony_ci return arg 10740681896Sopenharmony_ci 10840681896Sopenharmony_ci 10940681896Sopenharmony_cidef sign_cert_check(arg): 11040681896Sopenharmony_ci """ 11140681896Sopenharmony_ci Argument check, which is used to check whether 11240681896Sopenharmony_ci the specified arg is a sign cert. 11340681896Sopenharmony_ci :param arg: the arg to check. 11440681896Sopenharmony_ci :return: Check result, which is False if the arg is invalid. 11540681896Sopenharmony_ci """ 11640681896Sopenharmony_ci if arg != "ON_SERVER" and not os.path.isfile(arg): 11740681896Sopenharmony_ci UPDATE_LOGGER.print_log( 11840681896Sopenharmony_ci "FileNotFoundError, path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 11940681896Sopenharmony_ci return False 12040681896Sopenharmony_ci return arg 12140681896Sopenharmony_ci 12240681896Sopenharmony_ci 12340681896Sopenharmony_cidef check_update_package(arg): 12440681896Sopenharmony_ci """ 12540681896Sopenharmony_ci Argument check, which is used to check whether 12640681896Sopenharmony_ci the update package path exists. 12740681896Sopenharmony_ci :param arg: The arg to check. 12840681896Sopenharmony_ci :return: Check result 12940681896Sopenharmony_ci """ 13040681896Sopenharmony_ci make_dir_path = None 13140681896Sopenharmony_ci if os.path.exists(arg): 13240681896Sopenharmony_ci if os.path.isfile(arg): 13340681896Sopenharmony_ci UPDATE_LOGGER.print_log( 13440681896Sopenharmony_ci "Update package must be a dir path, not a file path. " 13540681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 13640681896Sopenharmony_ci return False 13740681896Sopenharmony_ci else: 13840681896Sopenharmony_ci try: 13940681896Sopenharmony_ci UPDATE_LOGGER.print_log( 14040681896Sopenharmony_ci "Update package path does not exist. The dir will be created!" 14140681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.WARNING_LOG) 14240681896Sopenharmony_ci os.makedirs(arg) 14340681896Sopenharmony_ci make_dir_path = arg 14440681896Sopenharmony_ci except OSError: 14540681896Sopenharmony_ci UPDATE_LOGGER.print_log( 14640681896Sopenharmony_ci "Make update package path dir failed! " 14740681896Sopenharmony_ci "path: %s" % arg, UPDATE_LOGGER.ERROR_LOG) 14840681896Sopenharmony_ci return False 14940681896Sopenharmony_ci return arg 15040681896Sopenharmony_ci 15140681896Sopenharmony_ci 15240681896Sopenharmony_ciclass UpdateToolLogger: 15340681896Sopenharmony_ci """ 15440681896Sopenharmony_ci Global log class 15540681896Sopenharmony_ci """ 15640681896Sopenharmony_ci INFO_LOG = 'INFO_LOG' 15740681896Sopenharmony_ci WARNING_LOG = 'WARNING_LOG' 15840681896Sopenharmony_ci ERROR_LOG = 'ERROR_LOG' 15940681896Sopenharmony_ci LOG_TYPE = (INFO_LOG, WARNING_LOG, ERROR_LOG) 16040681896Sopenharmony_ci 16140681896Sopenharmony_ci def __init__(self, output_type='console'): 16240681896Sopenharmony_ci self.__logger_obj = self.__get_logger_obj(output_type=output_type) 16340681896Sopenharmony_ci 16440681896Sopenharmony_ci @staticmethod 16540681896Sopenharmony_ci def __get_logger_obj(output_type='console'): 16640681896Sopenharmony_ci ota_logger = logging.getLogger(__name__) 16740681896Sopenharmony_ci ota_logger.setLevel(level=logging.INFO) 16840681896Sopenharmony_ci formatter = logging.Formatter( 16940681896Sopenharmony_ci '%(asctime)s %(levelname)s : %(message)s', 17040681896Sopenharmony_ci "%Y-%m-%d %H:%M:%S") 17140681896Sopenharmony_ci if output_type == 'console': 17240681896Sopenharmony_ci console_handler = logging.StreamHandler() 17340681896Sopenharmony_ci console_handler.setLevel(logging.INFO) 17440681896Sopenharmony_ci console_handler.setFormatter(formatter) 17540681896Sopenharmony_ci ota_logger.addHandler(console_handler) 17640681896Sopenharmony_ci elif output_type == 'file': 17740681896Sopenharmony_ci file_handler = logging.FileHandler("UpdateToolLog.txt") 17840681896Sopenharmony_ci file_handler.setLevel(logging.INFO) 17940681896Sopenharmony_ci file_handler.setFormatter(formatter) 18040681896Sopenharmony_ci ota_logger.addHandler(file_handler) 18140681896Sopenharmony_ci return ota_logger 18240681896Sopenharmony_ci 18340681896Sopenharmony_ci def print_log(self, msg, log_type=INFO_LOG): 18440681896Sopenharmony_ci """ 18540681896Sopenharmony_ci Print log information. 18640681896Sopenharmony_ci :param msg: log information 18740681896Sopenharmony_ci :param log_type: log type 18840681896Sopenharmony_ci :return: 18940681896Sopenharmony_ci """ 19040681896Sopenharmony_ci if log_type == self.LOG_TYPE[0]: 19140681896Sopenharmony_ci self.__logger_obj.info(msg) 19240681896Sopenharmony_ci elif log_type == self.LOG_TYPE[1]: 19340681896Sopenharmony_ci self.__logger_obj.warning(msg) 19440681896Sopenharmony_ci elif log_type == self.LOG_TYPE[2]: 19540681896Sopenharmony_ci self.__logger_obj.error(msg) 19640681896Sopenharmony_ci else: 19740681896Sopenharmony_ci self.__logger_obj.error("Unknown log type! %s", log_type) 19840681896Sopenharmony_ci return False 19940681896Sopenharmony_ci return True 20040681896Sopenharmony_ci 20140681896Sopenharmony_ci def print_uncaught_exception_msg(self, msg, exc_info): 20240681896Sopenharmony_ci """ 20340681896Sopenharmony_ci Print log when an uncaught exception occurs. 20440681896Sopenharmony_ci :param msg: Uncaught exception 20540681896Sopenharmony_ci :param exc_info: information about the uncaught exception 20640681896Sopenharmony_ci """ 20740681896Sopenharmony_ci self.__logger_obj.error(msg, exc_info=exc_info) 20840681896Sopenharmony_ci 20940681896Sopenharmony_ci 21040681896Sopenharmony_ciUPDATE_LOGGER = UpdateToolLogger() 21140681896Sopenharmony_ci 21240681896Sopenharmony_ci 21340681896Sopenharmony_cidef load_public_cert(sign_cert): 21440681896Sopenharmony_ci with open(sign_cert, 'rb') as cert_file: 21540681896Sopenharmony_ci der_bytes = cert_file.read() 21640681896Sopenharmony_ci if pem.detect(der_bytes): 21740681896Sopenharmony_ci type_name, headers, der_bytes = pem.unarmor(der_bytes) 21840681896Sopenharmony_ci 21940681896Sopenharmony_ci return x509.Certificate.load(der_bytes) 22040681896Sopenharmony_ci 22140681896Sopenharmony_ci 22240681896Sopenharmony_cidef calculate_package_hash(package_path): 22340681896Sopenharmony_ci """ 22440681896Sopenharmony_ci :return: (hash) for path using hashlib.sha256() 22540681896Sopenharmony_ci """ 22640681896Sopenharmony_ci hash_sha256 = hashlib.sha256() 22740681896Sopenharmony_ci length = 0 22840681896Sopenharmony_ci 22940681896Sopenharmony_ci remain_len = os.path.getsize(package_path) - ZIP_ECOD_LENGTH 23040681896Sopenharmony_ci with open(package_path, 'rb') as package_file: 23140681896Sopenharmony_ci while remain_len > BLCOK_SIZE: 23240681896Sopenharmony_ci hash_sha256.update(package_file.read(BLCOK_SIZE)) 23340681896Sopenharmony_ci remain_len -= BLCOK_SIZE 23440681896Sopenharmony_ci if remain_len > 0: 23540681896Sopenharmony_ci hash_sha256.update(package_file.read(remain_len)) 23640681896Sopenharmony_ci 23740681896Sopenharmony_ci return hash_sha256.digest() 23840681896Sopenharmony_ci 23940681896Sopenharmony_ci 24040681896Sopenharmony_cidef sign_digest_with_pss(digset, private_key_file): 24140681896Sopenharmony_ci # read private key from pem file 24240681896Sopenharmony_ci try: 24340681896Sopenharmony_ci with open(private_key_file, 'rb') as f_r: 24440681896Sopenharmony_ci key_data = f_r.read() 24540681896Sopenharmony_ci 24640681896Sopenharmony_ci private_key = serialization.load_pem_private_key( 24740681896Sopenharmony_ci key_data, 24840681896Sopenharmony_ci password=None, 24940681896Sopenharmony_ci backend=default_backend()) 25040681896Sopenharmony_ci pad = padding.PSS( 25140681896Sopenharmony_ci mgf=padding.MGF1(hashes.SHA256()), 25240681896Sopenharmony_ci salt_length=padding.PSS.MAX_LENGTH) 25340681896Sopenharmony_ci 25440681896Sopenharmony_ci signature = private_key.sign( 25540681896Sopenharmony_ci digset, 25640681896Sopenharmony_ci pad, 25740681896Sopenharmony_ci hashes.SHA256() 25840681896Sopenharmony_ci ) 25940681896Sopenharmony_ci except (OSError, ValueError): 26040681896Sopenharmony_ci return False 26140681896Sopenharmony_ci return signature 26240681896Sopenharmony_ci 26340681896Sopenharmony_ci 26440681896Sopenharmony_cidef sign_digest(digset, private_key_file): 26540681896Sopenharmony_ci # read private key from pem file 26640681896Sopenharmony_ci try: 26740681896Sopenharmony_ci with open(private_key_file, 'rb') as f_r: 26840681896Sopenharmony_ci key_data = f_r.read() 26940681896Sopenharmony_ci 27040681896Sopenharmony_ci private_key = serialization.load_pem_private_key( 27140681896Sopenharmony_ci key_data, 27240681896Sopenharmony_ci password=None, 27340681896Sopenharmony_ci backend=default_backend()) 27440681896Sopenharmony_ci 27540681896Sopenharmony_ci signature = private_key.sign( 27640681896Sopenharmony_ci digset, 27740681896Sopenharmony_ci padding.PKCS1v15(), 27840681896Sopenharmony_ci hashes.SHA256() 27940681896Sopenharmony_ci ) 28040681896Sopenharmony_ci except (OSError, ValueError): 28140681896Sopenharmony_ci return False 28240681896Sopenharmony_ci return signature 28340681896Sopenharmony_ci 28440681896Sopenharmony_ci 28540681896Sopenharmony_cidef create_encap_content_info(diget): 28640681896Sopenharmony_ci if not diget: 28740681896Sopenharmony_ci UPDATE_LOGGER.print_log("calc package hash failed! file: %s", 28840681896Sopenharmony_ci log_type=UPDATE_LOGGER.ERROR_LOG) 28940681896Sopenharmony_ci return False 29040681896Sopenharmony_ci content_header = struct.pack(CONTENT_INFO_FORMAT, DIGEST_SHA256, 29140681896Sopenharmony_ci SHA256_HASH_LEN, diget) 29240681896Sopenharmony_ci return content_header 29340681896Sopenharmony_ci 29440681896Sopenharmony_ci 29540681896Sopenharmony_cidef write_signed_package(unsigned_package, signature, signed_package): 29640681896Sopenharmony_ci """ 29740681896Sopenharmony_ci :Write signature to signed package 29840681896Sopenharmony_ci """ 29940681896Sopenharmony_ci signature_size = len(signature) 30040681896Sopenharmony_ci signature_total_size = signature_size + FOOTER_LENGTH 30140681896Sopenharmony_ci 30240681896Sopenharmony_ci package_fd = os.open(signed_package, os.O_RDWR | os.O_CREAT, 0o755) 30340681896Sopenharmony_ci f_signed = os.fdopen(package_fd, 'wb') 30440681896Sopenharmony_ci 30540681896Sopenharmony_ci remain_len = os.path.getsize(unsigned_package) - 2 30640681896Sopenharmony_ci with open(unsigned_package, 'rb') as f_unsign: 30740681896Sopenharmony_ci while remain_len > BLCOK_SIZE: 30840681896Sopenharmony_ci f_signed.write(f_unsign.read(BLCOK_SIZE)) 30940681896Sopenharmony_ci remain_len -= BLCOK_SIZE 31040681896Sopenharmony_ci if remain_len > 0: 31140681896Sopenharmony_ci f_signed.write(f_unsign.read(remain_len)) 31240681896Sopenharmony_ci 31340681896Sopenharmony_ci zip_comment_len = struct.pack(ZIP_EOCD_COMMENT_LEN_FORMAT, 31440681896Sopenharmony_ci signature_total_size) 31540681896Sopenharmony_ci f_signed.write(zip_comment_len) 31640681896Sopenharmony_ci 31740681896Sopenharmony_ci f_signed.write(signature) 31840681896Sopenharmony_ci footter = struct.pack(SIGANTURE_FOOTER_FORMAT, signature_total_size, 31940681896Sopenharmony_ci 0xffff, signature_total_size) 32040681896Sopenharmony_ci f_signed.write(footter) 32140681896Sopenharmony_ci f_signed.close() 32240681896Sopenharmony_ci 32340681896Sopenharmony_ci 32440681896Sopenharmony_cidef sign_ota_package(package_path, signed_package, private_key, sign_cert): 32540681896Sopenharmony_ci digest = calculate_package_hash(package_path) 32640681896Sopenharmony_ci data = create_encap_content_info(digest) 32740681896Sopenharmony_ci signature = sign_digest(digest, private_key) 32840681896Sopenharmony_ci 32940681896Sopenharmony_ci digest_fd = os.open("digest", os.O_RDWR | os.O_CREAT, 0o755) 33040681896Sopenharmony_ci digest_file = os.fdopen(digest_fd, 'wb') 33140681896Sopenharmony_ci digest_file.write(digest) 33240681896Sopenharmony_ci digest_file.close() 33340681896Sopenharmony_ci 33440681896Sopenharmony_ci signatute_fd = os.open("signature", os.O_RDWR | os.O_CREAT, 0o755) 33540681896Sopenharmony_ci signatute_file = os.fdopen(signatute_fd, 'wb') 33640681896Sopenharmony_ci signatute_file.write(signature) 33740681896Sopenharmony_ci signatute_file.close() 33840681896Sopenharmony_ci 33940681896Sopenharmony_ci # Creating a SignedData object from cms 34040681896Sopenharmony_ci signed_data = cms.SignedData() 34140681896Sopenharmony_ci signed_data['version'] = 'v1' 34240681896Sopenharmony_ci signed_data['encap_content_info'] = util.OrderedDict([ 34340681896Sopenharmony_ci ('content_type', 'data'), 34440681896Sopenharmony_ci ('content', data)]) 34540681896Sopenharmony_ci 34640681896Sopenharmony_ci signed_data['digest_algorithms'] = [util.OrderedDict([ 34740681896Sopenharmony_ci ('algorithm', 'sha256'), 34840681896Sopenharmony_ci ('parameters', None)])] 34940681896Sopenharmony_ci 35040681896Sopenharmony_ci cert = load_public_cert(sign_cert) 35140681896Sopenharmony_ci 35240681896Sopenharmony_ci # Adding this certificate to SignedData object 35340681896Sopenharmony_ci signed_data['certificates'] = [cert] 35440681896Sopenharmony_ci 35540681896Sopenharmony_ci # Setting signer info section 35640681896Sopenharmony_ci signer_info = cms.SignerInfo() 35740681896Sopenharmony_ci signer_info['version'] = 'v1' 35840681896Sopenharmony_ci signer_info['digest_algorithm'] = util.OrderedDict([ 35940681896Sopenharmony_ci ('algorithm', 'sha256'), 36040681896Sopenharmony_ci ('parameters', None)]) 36140681896Sopenharmony_ci signer_info['signature_algorithm'] = util.OrderedDict([ 36240681896Sopenharmony_ci ('algorithm', 'sha256_rsa'), 36340681896Sopenharmony_ci ('parameters', None)]) 36440681896Sopenharmony_ci 36540681896Sopenharmony_ci issuer = cert.issuer 36640681896Sopenharmony_ci serial_number = cert.serial_number 36740681896Sopenharmony_ci issuer_and_serial = cms.IssuerAndSerialNumber() 36840681896Sopenharmony_ci issuer_and_serial['issuer'] = cert.issuer 36940681896Sopenharmony_ci issuer_and_serial['serial_number'] = cert.serial_number 37040681896Sopenharmony_ci 37140681896Sopenharmony_ci key_id = cert.key_identifier_value.native 37240681896Sopenharmony_ci signer_info['sid'] = cms.SignerIdentifier({ 37340681896Sopenharmony_ci 'issuer_and_serial_number': issuer_and_serial}) 37440681896Sopenharmony_ci 37540681896Sopenharmony_ci signer_info['signature'] = signature 37640681896Sopenharmony_ci # Adding SignerInfo object to SignedData object 37740681896Sopenharmony_ci signed_data['signer_infos'] = [signer_info] 37840681896Sopenharmony_ci 37940681896Sopenharmony_ci # Writing everything into ASN.1 object 38040681896Sopenharmony_ci asn1obj = cms.ContentInfo() 38140681896Sopenharmony_ci asn1obj['content_type'] = 'signed_data' 38240681896Sopenharmony_ci asn1obj['content'] = signed_data 38340681896Sopenharmony_ci 38440681896Sopenharmony_ci # This asn1obj can be dumped to a disk using dump() method (DER format) 38540681896Sopenharmony_ci write_signed_package(package_path, asn1obj.dump(), signed_package) 38640681896Sopenharmony_ci return True 38740681896Sopenharmony_ci 38840681896Sopenharmony_ci 38940681896Sopenharmony_cidef build_module_package(package_name, target_package, update_package, private_key, sign_cert): 39040681896Sopenharmony_ci unsigned_package = os.path.join( 39140681896Sopenharmony_ci update_package, '%s_unsigned.zip' % package_name) 39240681896Sopenharmony_ci 39340681896Sopenharmony_ci zip_file = zipfile.ZipFile(unsigned_package, 'w') 39440681896Sopenharmony_ci # add module.img to update package 39540681896Sopenharmony_ci img_file_path = os.path.join(target_package, 'module.img') 39640681896Sopenharmony_ci if os.path.exists(img_file_path): 39740681896Sopenharmony_ci zip_file.write(img_file_path, "module.img") 39840681896Sopenharmony_ci # add config.json to update package 39940681896Sopenharmony_ci module_file_path = os.path.join(target_package, 'config.json') 40040681896Sopenharmony_ci zip_file.write(module_file_path, "config.json") 40140681896Sopenharmony_ci # add pub_key.pem to update package 40240681896Sopenharmony_ci pub_key_file_path = os.path.join(target_package, 'pub_key.pem') 40340681896Sopenharmony_ci if os.path.exists(pub_key_file_path): 40440681896Sopenharmony_ci zip_file.write(pub_key_file_path, 'pub_key.pem') 40540681896Sopenharmony_ci zip_file.close() 40640681896Sopenharmony_ci 40740681896Sopenharmony_ci # align package 40840681896Sopenharmony_ci align_package = os.path.join( 40940681896Sopenharmony_ci update_package, '%s_align.zip' % package_name) 41040681896Sopenharmony_ci align_cmd = ['java', '-jar', SIGN_TOOL_PATH, unsigned_package, align_package, '4096'] 41140681896Sopenharmony_ci subprocess.call(align_cmd, shell=False) 41240681896Sopenharmony_ci if not os.path.exists(align_package): 41340681896Sopenharmony_ci UPDATE_LOGGER.print_log("align package failed", log_type=UPDATE_LOGGER.ERROR_LOG) 41440681896Sopenharmony_ci return False 41540681896Sopenharmony_ci 41640681896Sopenharmony_ci # sign package 41740681896Sopenharmony_ci signed_package = os.path.join( 41840681896Sopenharmony_ci update_package, '%s.zip' % package_name) 41940681896Sopenharmony_ci if os.path.exists(signed_package): 42040681896Sopenharmony_ci os.remove(signed_package) 42140681896Sopenharmony_ci 42240681896Sopenharmony_ci sign_result = sign_ota_package( 42340681896Sopenharmony_ci align_package, 42440681896Sopenharmony_ci signed_package, 42540681896Sopenharmony_ci private_key, 42640681896Sopenharmony_ci sign_cert) 42740681896Sopenharmony_ci 42840681896Sopenharmony_ci if not sign_result: 42940681896Sopenharmony_ci UPDATE_LOGGER.print_log("Sign module package fail", UPDATE_LOGGER.ERROR_LOG) 43040681896Sopenharmony_ci return False 43140681896Sopenharmony_ci if os.path.exists(align_package): 43240681896Sopenharmony_ci os.remove(align_package) 43340681896Sopenharmony_ci if os.path.exists(unsigned_package): 43440681896Sopenharmony_ci os.remove(unsigned_package) 43540681896Sopenharmony_ci 43640681896Sopenharmony_ci return True 43740681896Sopenharmony_ci 43840681896Sopenharmony_ci 43940681896Sopenharmony_cidef main(argv): 44040681896Sopenharmony_ci """ 44140681896Sopenharmony_ci Entry function. 44240681896Sopenharmony_ci """ 44340681896Sopenharmony_ci parser = argparse.ArgumentParser() 44440681896Sopenharmony_ci parser.add_argument("target_package", type=target_package_check, 44540681896Sopenharmony_ci help="Target package file path.") 44640681896Sopenharmony_ci parser.add_argument("update_package", type=check_update_package, 44740681896Sopenharmony_ci help="Update package file path.") 44840681896Sopenharmony_ci parser.add_argument("-pk", "--private_key", type=private_key_check, 44940681896Sopenharmony_ci default=None, help="Private key file path.") 45040681896Sopenharmony_ci parser.add_argument("-sc", "--sign_cert", type=sign_cert_check, 45140681896Sopenharmony_ci default=None, help="Sign cert file path.") 45240681896Sopenharmony_ci parser.add_argument("-pn", "--package_name", type=package_name_check, 45340681896Sopenharmony_ci default=None, help="Package name.") 45440681896Sopenharmony_ci 45540681896Sopenharmony_ci args = parser.parse_args(argv) 45640681896Sopenharmony_ci 45740681896Sopenharmony_ci # Generate the module package. 45840681896Sopenharmony_ci build_re = build_module_package(args.package_name, args.target_package, 45940681896Sopenharmony_ci args.update_package, args.private_key, args.sign_cert) 46040681896Sopenharmony_ci 46140681896Sopenharmony_ciif __name__ == '__main__': 46240681896Sopenharmony_ci main(sys.argv[1:]) 463