1#!/usr/bin/env python 2# coding:utf-8 3 4# 5# Copyright (C) 2022 Huawei Technologies Co., Ltd. 6# Licensed under the Mulan PSL v2. 7# You can use this software according to the terms and conditions of the Mulan 8# PSL v2. 9# You may obtain a copy of Mulan PSL v2 at: 10# http://license.coscl.org.cn/MulanPSL2 11# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY 12# KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO 13# NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 14# See the Mulan PSL v2 for more details. 15# 16 17import os 18import stat 19import sys 20import subprocess 21import logging 22import getpass 23from generate_hash import gen_hash 24logging.basicConfig(level=logging.INFO) 25 26HASH256 = 0 27HASH512 = 1 28 29 30def run_cmd(command): 31 ret = subprocess.run(command, shell=False, check=True) 32 if ret.returncode != 0: 33 logging.error("run command failed.") 34 sys.exit(1) 35 36 37def gen_identity(): 38 env = os.environ 39 user_id = env.get("ONLINE_USERNAME") 40 password = env.get("ONLINE_PASSWD") 41 if user_id == "" or user_id is None: 42 logging.critical("Error: Please do like this, or set ONLINE_USERNAME in .bashrc.") 43 user_id = input("Please input your account:") 44 45 if password == "" or password is None: 46 logging.critical("Error: Please do like this, or set ONLINE_PASSWD in .bashrc.") 47 password = getpass.getpass("Please input your password:") 48 49 return (user_id, password) 50 51 52def gen_jar_path(): 53 env = os.environ 54 jar_path = env.get("NATIVE_CA_SIGN_JAR_PATH") 55 if jar_path == "" or jar_path is None: 56 logging.critical("Set jar tool path") 57 jar_path = input("Please input NativeCASign.jar path:") 58 return jar_path 59 60def get_add_opens_flag(cfg): 61 add_opens_flag = "" 62 if cfg.jdk_version == "11": 63 add_opens_flag = "--add-opens=java.base/java.lang=ALL-UNNAMED" 64 return add_opens_flag 65 66def signed_by_jar_tool(cfg, raw_data, hash_file_path, uuid_str, raw_data_path, out_file_path): 67 """ signed by sign server using sign.jar tool """ 68 (user_id, password) = gen_identity() 69 jar_path = gen_jar_path() 70 cmd = "" 71 add_opens_flag = get_add_opens_flag(cfg) 72 if cfg.sign_key_len == "2048": 73 gen_hash(cfg.hash_type, raw_data, hash_file_path) 74 cmd = 'java %s -jar %s %s %s %s %s %s %s' \ 75 % (add_opens_flag, jar_path, cfg.server_ip, user_id, password, \ 76 cfg.sign_key, hash_file_path, out_file_path) 77 elif cfg.sign_key_len == "4096": 78 if cfg.hash_type == '0': 79 # sha256 80 cmd = 'java %s -jar %s -uuid %s \ 81 -signAlg SHA256withRSA/PSS %s %s %s %s %s %s' \ 82 % (add_opens_flag, jar_path, uuid_str, cfg.server_ip, user_id, password, \ 83 cfg.sign_key, raw_data_path, out_file_path) 84 else: 85 # sha512 86 cmd = 'java %s -jar %s -uuid %s \ 87 -signAlg SHA512withRSA/PSS %s %s %s %s %s %s' \ 88 % (add_opens_flag, jar_path, uuid_str, cfg.server_ip, user_id, password, \ 89 cfg.sign_key, raw_data_path, out_file_path) 90 logging.info("sign key len : %s ", cfg.sign_key_len) 91 try: 92 logging.info("signing...") 93 subprocess.check_output(cmd.split(), shell=False) 94 except subprocess.CalledProcessError as exception: 95 logging.error("sign operation failed %s", exception.output) 96 logging.error("native ca sign jar path %s", jar_path) 97 exit(0) 98 99 100def gen_ta_signature(cfg, uuid_str, raw_data, raw_data_path, hash_file_path, \ 101 out_file_path, out_path, key_info_data): 102 fd_raw = os.open(raw_data_path, os.O_WRONLY | os.O_CREAT, \ 103 stat.S_IWUSR | stat.S_IRUSR) 104 raw_fp = os.fdopen(fd_raw, "wb") 105 raw_fp.write(raw_data) 106 raw_fp.close() 107 108 if cfg.sign_type == '0': # don't sign for debug version 109 logging.critical("generate dummy signature for DEBUG version") 110 fd_file = os.open(out_file_path, os.O_WRONLY | os.O_CREAT, \ 111 stat.S_IWUSR | stat.S_IRUSR) 112 file_op = os.fdopen(fd_file, "wb") 113 file_op.write(str.encode('\0' * 256, encoding = 'utf-8')) 114 file_op.close() 115 elif cfg.sign_type == '1': # signed with local key 116 if cfg.sign_alg == "ECDSA": 117 if int(cfg.hash_type) == HASH256: 118 cmd = ["openssl", "dgst", "-sha256", "-sign", cfg.sign_key, \ 119 "-out", out_file_path, raw_data_path] 120 else: 121 cmd = ["openssl", "dgst", "-sha512", "-sign", cfg.sign_key, \ 122 "-out", out_file_path, raw_data_path] 123 run_cmd(cmd) 124 logging.info("Sign sec Success") 125 else: # rsa 126 if cfg.padding_type == '1': # pss 127 if cfg.hash_type == '0': # sha256 128 cmd = "openssl dgst -sign {} -sha256 -sigopt \ 129 rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \ 130 -out {} {}".format(cfg.sign_key, out_file_path, raw_data_path) 131 else: # sha512 132 cmd = "openssl dgst -sign {} -sha512 -sigopt \ 133 rsa_padding_mode:pss -sigopt rsa_pss_saltlen:-1 \ 134 -out {} {}".format(cfg.sign_key, out_file_path, raw_data_path) 135 run_cmd(cmd.split()) 136 logging.info("pss sign sec Success") 137 else: 138 logging.error("padding type %s is not support!", cfg.padding_type) 139 exit(0) 140 elif cfg.sign_type == '2': # signed by sign server 141 signed_by_jar_tool(cfg, raw_data, hash_file_path, uuid_str, raw_data_path, out_file_path) 142 else: 143 logging.error("unhandled signtype %s", cfg.sign_type) 144 145 return 146 147