• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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