diff --git a/OAT.xml b/OAT.xml
index b2fcfdde6d957f306ffc290e708fb65619e6d1fb..f8a62daa9ab34fd7cfd3a6b4f9e36d4d4cb886e9 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -31,9 +31,11 @@
-
+
+
+
@@ -42,13 +44,18 @@
-
+
+
+
+
+
+
@@ -61,10 +68,12 @@
+
-
+
+
diff --git a/hapsigntool_cpp/bundle.json b/hapsigntool_cpp/bundle.json
new file mode 100644
index 0000000000000000000000000000000000000000..5e82001957de2fd9de702498cf924593d75539be
--- /dev/null
+++ b/hapsigntool_cpp/bundle.json
@@ -0,0 +1,55 @@
+{
+ "name": "@ohos/hapsigner",
+ "version": "3.1",
+ "description": "hap包签名工具,支持.hsp、.hqf、.hap和.app等文件签名",
+ "homePage": "https://gitee.com/openharmony",
+ "license": "Apache License 2.0",
+ "repository": "https://gitee.com/openharmony/developtools_hapsigner",
+ "domain": "os",
+ "language": "",
+ "publishAs": "code-segment",
+ "private": false,
+ "scripts": {},
+ "tags": [
+ "developtools"
+ ],
+ "keywords": [
+ "hapsigner"
+ ],
+ "envs": {},
+ "dirs": {},
+ "segment": {
+ "destPath": "developtools/hapsigner"
+ },
+ "component": {
+ "name": "hapsigner",
+ "subsystem": "developtools",
+ "syscap": [],
+ "features": [],
+ "adapted_system_type": [ "standard" ],
+ "rom": "0KB",
+ "ram": "0KB",
+ "deps": {
+ "components": [
+ "c_utils",
+ "hilog",
+ "json"
+ ],
+ "third_party": [
+ "bzip2",
+ "openssl",
+ "jsoncpp",
+ "zlib"
+ ]
+ },
+ "build": {
+ "sub_component": [
+ "//developtools/hapsigner/hapsigntool_cpp/services:hap-sign-tool"
+ ],
+ "inner_kits": [],
+ "test": [
+ "//developtools/hapsigner/hapsigntool_cpp/test/unittest:hapsigntool_pc_unittest"
+ ]
+ }
+ }
+}
diff --git a/hapsigntool_cpp/services/BUILD.gn b/hapsigntool_cpp/services/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..11d6ef075a43af2ec4e4c12456eb7e63b3f8cb56
--- /dev/null
+++ b/hapsigntool_cpp/services/BUILD.gn
@@ -0,0 +1,120 @@
+# Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../signature_tools.gni")
+import("./cmd/signature_tools_cmd.gni")
+import("./codesigning/signature_tools_codesigning.gni")
+import("./common/signature_tools_common.gni")
+import("./hap/signature_tools_hap.gni")
+import("./profile/signature_tools_profile.gni")
+import("./utils/signature_tools_utils.gni")
+import("./zip/signature_tools_zip.gni")
+
+import("//build/ohos.gni")
+
+ohos_copy("copy_signature_tools_resource") {
+ sources = [
+ "../../dist/OpenHarmony.p12",
+ "../../dist/OpenHarmonyApplication.pem",
+ "../../dist/OpenHarmonyProfileDebug.pem",
+ "../../dist/OpenHarmonyProfileRelease.pem",
+ "../../dist/SgnedReleaseProfileTemplate.p7b",
+ "../../dist/UnsgnedDebugProfileTemplate.json",
+ "../../dist/UnsgnedReleasedProfileTemplate.json",
+ "config/help.txt",
+ ]
+ outputs =
+ [ "${target_out_dir}/toolchains/hapsigntool_pc/{{source_file_part}}" ]
+ module_source_dir = target_out_dir + "/toolchains/hapsigntool_pc"
+ module_install_name = ""
+ part_name = "hapsigner"
+ subsystem_name = "developtools"
+}
+
+signature_tools_main_include = [
+ "${signature_tools_service}/api/include",
+ "${signature_tools_service}/signer/include",
+ "//third_party/openssl/include",
+ "//third_party/openssl/crypto/pkcs12",
+]
+
+signature_tools_main_src = [
+ "main.cpp",
+ "${signature_tools_service}/api/src/localization_adapter.cpp",
+ "${signature_tools_service}/api/src/sign_tool_service_impl.cpp",
+ "${signature_tools_service}/api/src/cert_tools.cpp",
+ "${signature_tools_service}/signer/src/signer_factory.cpp",
+ "${signature_tools_service}/signer/src/local_signer.cpp",
+]
+
+ohos_executable("hap-sign-tool") {
+ signature_tools_main_include += signature_tools_utils_include
+ signature_tools_main_include += signature_tools_zip_include
+
+ # signature_tools_main_include += signature_tools_entity_include
+ signature_tools_main_include += signature_tools_codesigning_include
+ signature_tools_main_include += signature_tools_common_include
+ signature_tools_main_include += signature_tools_hap_include
+ signature_tools_main_include += signature_tools_profile_include
+ signature_tools_main_include += signature_tools_cmd_include
+
+ # 在 //developtools/signaturetools/services/utils 模块里面定义编译脚本 signature_tools_utils.gni
+ signature_tools_main_src += signature_tools_utils_src
+
+ # 在 //developtools/signaturetools/services/zip 模块里面定义编译脚本 signature_tools_zip.gni
+ signature_tools_main_src += signature_tools_zip_src
+
+ # signature_tools_main_src += signature_tools_entity_src
+ signature_tools_main_src += signature_tools_codesigning_src
+ signature_tools_main_src += signature_tools_common_src
+ signature_tools_main_src += signature_tools_hap_src
+ signature_tools_main_src += signature_tools_profile_src
+ signature_tools_main_src += signature_tools_cmd_src
+
+ include_dirs = signature_tools_main_include
+ sources = signature_tools_main_src
+
+ defines = [
+ "HI_LOG_ENABLE",
+ "SIGNATURE_LOG_TAG=\"Signature_Tools\"",
+ "LOG_DOMAIN=0xD004100",
+ ]
+
+ deps = [
+ "//third_party/bzip2:libbz2",
+ "//third_party/openssl:libcrypto_shared",
+ "//third_party/openssl:libssl_shared",
+ "//third_party/zlib:shared_libz",
+ ]
+
+ external_deps = [
+ "c_utils:utils",
+ "hilog:libhilog",
+ "json:nlohmann_json_static",
+ ]
+
+ cflags_cc = [
+ "-std=c++17",
+ "-fno-rtti",
+ ]
+
+ cflags = [
+ "-fno-rtti",
+ "-Wno-c++20-extensions",
+ ]
+
+ install_images = [ "system" ]
+ install_enable = true
+ part_name = "hapsigner"
+ subsystem_name = "developtools"
+}
diff --git a/hapsigntool_cpp/services/api/include/cert_tools.h b/hapsigntool_cpp/services/api/include/cert_tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..4e8c609d4b2095b757c09ca4bd15d9620ffafbf9
--- /dev/null
+++ b/hapsigntool_cpp/services/api/include/cert_tools.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SIGNATRUETOOLS_CERT_TOOLS_H
+#define SIGNATRUETOOLS_CERT_TOOLS_H
+
+#include "cert_dn_utils.h"
+#include "openssl/x509v3.h"
+#include "openssl/rand.h"
+#include "localization_adapter.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+class CertTools {
+public:
+ CertTools() = default;
+ ~CertTools() = default;
+
+ static X509* GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options);
+ static X509* GenerateSubCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options);
+ static X509* GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options);
+ static bool SaveCertTofile(const std::string& filename, X509* cert);
+ static X509_REQ* GenerateCsr(EVP_PKEY* evpPkey, std::string signAlgorithm, std::string subject);
+ static X509* SignCsrGenerateCert(X509_REQ* rootcsr, X509_REQ* subcsr,
+ EVP_PKEY* keyPair, Options* options);
+ static std::string CsrToString(X509_REQ* csr);
+ static X509* GenerateEndCert(X509_REQ* csr, EVP_PKEY* issuerKeyPair,
+ LocalizationAdapter& adapter,
+ const char signCapacity[], int capacityLen);
+ static X509* ReadfileToX509(const std::string& filename);
+ static bool SetBisicConstraintsPatchLen(Options* options, X509* cert);
+ static bool SetSubjectForCert(X509_REQ* certReq, X509* cert);
+ static bool SignForSubCert(X509* cert, X509_REQ* csr, X509_REQ* caReq,
+ EVP_PKEY* ca_prikey, Options* options);
+ static bool SetKeyUsage(X509* cert, Options* options);
+ static bool SetkeyUsageExt(X509* cert, Options* options);
+ static bool SetCertValidity(X509* cert, int validity);
+ static bool SerialNumberBuilder(long* serialNum);
+ static bool SetCertVersion(X509* cert, int versionNum);
+ static bool SetCertSerialNum(X509* cert, long serialNum);
+ static bool SetCertIssuerName(X509* cert, X509_NAME* issuer);
+ static bool SetCertSubjectName(X509* cert, X509_REQ* subjectCsr);
+ static bool SetCertValidityStartAndEnd(X509* cert, long vilidityStart, long vilidityEnd);
+ static bool SetCertPublickKey(X509* cert, X509_REQ* subjectCsr);
+ static bool SetBasicExt(X509* cert);
+ static bool SetkeyUsageExt(X509* cert);
+ static bool SetKeyUsageEndExt(X509* cert);
+ static bool SetKeyIdentifierExt(X509* cert);
+ static bool SetSignCapacityExt(X509* cert, const char signCapacity[], int capacityLen);
+ static bool SignCert(X509* cert, EVP_PKEY* privateKey, std::string signAlg);
+ static bool SetExpandedInformation(X509* cert, Options* options);
+ static bool SetPubkeyAndSignCert(X509* cert, X509_REQ* issuercsr,
+ X509_REQ* certReq, EVP_PKEY* keyPair, Options* options);
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_CERT_TOOLS_H
diff --git a/hapsigntool_cpp/services/api/include/localization_adapter.h b/hapsigntool_cpp/services/api/include/localization_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..fb879d112d32a165398b8ac579c0a662801e0af0
--- /dev/null
+++ b/hapsigntool_cpp/services/api/include/localization_adapter.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNATRUETOOLS_LOCALIIZATION_ADAPTER_H
+#define SIGNATRUETOOLS_LOCALIIZATION_ADAPTER_H
+
+#include
+#include
+
+#include "openssl/ssl.h"
+#include "openssl/pem.h"
+#include "openssl/err.h"
+#include "options.h"
+#include "key_store_helper.h"
+#include "cert_dn_utils.h"
+#include "signature_tools_log.h"
+#include "verify_hap_openssl_utils.h"
+namespace OHOS {
+namespace SignatureTools {
+class LocalizationAdapter {
+public:
+ LocalizationAdapter() = default;
+ LocalizationAdapter(Options* options);
+ ~LocalizationAdapter() = default;
+
+ int IsAliasExist(const std::string& alias);
+ EVP_PKEY* GetAliasKey(bool autoCreate);
+ void ResetPwd();
+ void SetIssuerKeyStoreFile(bool issuerKeyStoreFile);
+ int GetKeyPair(bool autoCreate, EVP_PKEY** keyPair);
+ STACK_OF(X509*) GetSignCertChain();
+ EVP_PKEY* GetIssureKeyByAlias();
+ bool IsOutFormChain();
+ X509* GetSubCaCertFile();
+ int IssuerKeyStoreFile(EVP_PKEY** keyPair, bool autoCreate);
+ int KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate);
+ const std::string GetSignAlg() const;
+ X509* GetCaCertFile();
+ std::vector GetCertsFromFile(std::string& certPath, const std::string& logTitle);
+ const std::string GetOutFile();
+ const std::string GetInFile();
+ Options* options;
+ std::unique_ptr keyStoreHelper;
+ bool IsRemoteSigner();
+ Options* GetOptions();
+ void AppAndProfileAssetsRealse(std::initializer_list keys,
+ std::initializer_list reqs,
+ std::initializer_list certs);
+private:
+ void ResetChars(char* chars);
+ bool isIssuerKeyStoreFile;
+ static constexpr int MIN_CERT_CHAIN_SIZE = 2;
+ static constexpr int MAX_CERT_CHAIN_SIZE = 3;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_LOCALIIZATION_ADAPTER_H
diff --git a/hapsigntool_cpp/services/api/include/service_api.h b/hapsigntool_cpp/services/api/include/service_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..968df287baec4243debdd77685da4c4383d2a455
--- /dev/null
+++ b/hapsigntool_cpp/services/api/include/service_api.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNERTOOLS_SERVICE_API_H
+#define SIGNERTOOLS_SERVICE_API_H
+
+#include "options.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+class ServiceApi {
+public:
+ ServiceApi() = default;
+ ~ServiceApi() = default;
+
+ virtual bool GenerateKeyStore(Options* params) = 0;
+ virtual bool GenerateCsr(Options* params) = 0;
+ virtual bool GenerateCert(Options* params) = 0;
+ virtual bool GenerateCA(Options* params) = 0;
+ virtual bool GenerateAppCert(Options* params) = 0;
+ virtual bool GenerateProfileCert(Options* params) = 0;
+ virtual bool SignProfile(Options* params) = 0;
+ virtual bool VerifyProfile(Options* params) = 0;
+ virtual bool SignHap(Options* params) = 0;
+ virtual bool VerifyHapSigner(Options* params) = 0;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNERTOOLS_SERVICE_API_H
\ No newline at end of file
diff --git a/hapsigntool_cpp/services/api/include/sign_tool_service_impl.h b/hapsigntool_cpp/services/api/include/sign_tool_service_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..b19208b65df5aa4548da65939d71891457f27d15
--- /dev/null
+++ b/hapsigntool_cpp/services/api/include/sign_tool_service_impl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SIGNATRUETOOLS_SIGNTOOLSERVICELMPL_H
+#define SIGNATRUETOOLS_SIGNTOOLSERVICELMPL_H
+
+#include "options.h"
+#include "file_utils.h"
+#include "cert_tools.h"
+#include "localization_adapter.h"
+#include "signature_tools_log.h"
+#include "service_api.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+class SignToolServiceImpl : public ServiceApi {
+public:
+ SignToolServiceImpl() = default;
+ virtual ~SignToolServiceImpl() = default;
+
+ bool GenerateCA(Options* options)override;
+ bool GenerateRootCertToFile(Options* options, EVP_PKEY* rootKey);
+ bool GenerateSubCertToFile(Options* options, EVP_PKEY* rootKey);
+ bool OutputModeOfCert(X509* cert, Options* options);
+ bool GenerateCert(Options* options)override;
+ bool GenerateKeyStore(Options* options)override;
+ bool GenerateCsr(Options* options)override;
+ bool OutputString(std::string content, std::string file);
+ bool GenerateAppCert(Options* option)override;
+ bool GenerateProfileCert(Options* options)override;
+ bool GetAndOutPutCert(LocalizationAdapter& adapter, X509* cert);
+ bool SignProfile(Options* options)override;
+ bool SignHap(Options* options)override;
+ bool VerifyProfile(Options* options)override;
+ bool OutPutCertChain(std::vector& certs, const std::string& outPutPath);
+ bool OutPutCert(X509* certs, const std::string& outPutPath);
+ static int GetProvisionContent(const std::string& input, std::string& ret);
+ bool PrintX509CertFromMemory(X509* cert);
+ bool PrintX509CertChainFromMemory(std::vector certs);
+ bool VerifyHapSigner(Options* option)override;
+ bool X509CertVerify(X509* cert, EVP_PKEY* privateKey);
+ X509_REQ* GetCsr(EVP_PKEY* keyPair, std::string signAlg, std::string subject);
+ int HandleIssuerKeyAliasEmpty(Options* options);
+ int HandleIsserKeyAliasNotEmpty(Options* options);
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_SIGNTOOLSERVICELMPL_H
diff --git a/hapsigntool_cpp/services/api/src/cert_tools.cpp b/hapsigntool_cpp/services/api/src/cert_tools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..52132e97d1ae12a46cba1d7eb616bde748e4e8d1
--- /dev/null
+++ b/hapsigntool_cpp/services/api/src/cert_tools.cpp
@@ -0,0 +1,782 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "cert_tools.h"
+#include "openssl/ec.h"
+#include "openssl/obj_mac.h"
+#include "openssl/asn1.h"
+#include "signature_tools_log.h"
+#include "constant.h"
+
+#define BASIC_NUMBER_TWO 2
+
+namespace OHOS {
+namespace SignatureTools {
+
+static std::unordered_map externDic{
+ {"digitalSignature", X509v3_KU_DIGITAL_SIGNATURE},
+ {"nonRepudiation", X509v3_KU_NON_REPUDIATION},
+ {"keyEncipherment", X509v3_KU_KEY_ENCIPHERMENT},
+ {"dataEncipherment", X509v3_KU_DATA_ENCIPHERMENT},
+ {"keyAgreement", X509v3_KU_KEY_AGREEMENT},
+ {"certificateSignature", X509v3_KU_KEY_CERT_SIGN},
+ {"crlSignature", X509v3_KU_CRL_SIGN},
+ {"encipherOnly", X509v3_KU_ENCIPHER_ONLY},
+ {"decipherOnly", X509v3_KU_DECIPHER_ONLY},
+
+};
+
+static std::unordered_map externKey{
+ {"serverAuthentication", "1.3.6.1.5.5.7.3.1"},
+ {"clientAuthentication", "1.3.6.1.5.5.7.3.2"},
+ {"codeSignature", "1.3.6.1.5.5.7.3.3"},
+ {"emailProtection", "1.3.6.1.5.5.7.3.4"},
+ {"smartCardLogin", "1.3.6.1.5.5.7.3.5"},
+ {"timestamp", "1.3.6.1.5.5.7.3.8"},
+ {"ocspSignature", "1.3.6.1.5.5.7.3.9"},
+
+};
+
+bool CertTools::SaveCertTofile(const std::string& filename, X509* cert)
+{
+ BIO* certBio = BIO_new_file(filename.data(), "w");
+ if (!certBio) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("BIO_new failed\n");
+ return false;
+ }
+
+ if (PEM_write_bio_X509(certBio, cert) < 0) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509 failed\n");
+ BIO_free(certBio);
+ return false;
+ }
+ BIO_free(certBio);
+ return true;
+}
+
+bool CertTools::SetBisicConstraintsPatchLen(Options* options, X509* cert)
+{
+ if (options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN) == 0) {
+ X509V3_CTX ctx;
+ X509V3_set_ctx_nodb(&ctx);
+ X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, "CA:TRUE, pathlen:0");
+ if (!ext) {
+ SIGNATURE_TOOLS_LOGE("create the expanding information failed\n");
+ goto err;
+ }
+
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("X509_add_ext failed\n");
+ X509_EXTENSION_free(ext);
+ goto err;
+ }
+ X509_EXTENSION_free(ext);
+ } else {
+ std::string setOptions =
+ "CA:TRUE, pathlen:" + std::to_string(options->GetInt(Options::BASIC_CONSTRAINTS_PATH_LEN));
+ X509V3_CTX ctx;
+ X509V3_set_ctx_nodb(&ctx);
+
+ X509_EXTENSION* ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_basic_constraints, setOptions.c_str());
+ if (!ext) {
+ SIGNATURE_TOOLS_LOGE("create the expanding information failed\n");
+ goto err;
+ }
+
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("X509_add_ext failed\n");
+ X509_EXTENSION_free(ext);
+ goto err;
+ }
+ X509_EXTENSION_free(ext);
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+bool CertTools::SignForSubCert(X509* cert, X509_REQ* subcsr, X509_REQ* rootcsr, EVP_PKEY* ca_prikey, Options* options)
+{
+ bool result = false;
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ EVP_PKEY* pubKey = X509_REQ_get_pubkey(subcsr);
+ if (pubKey == NULL) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_get_pubkey failed\n");
+ goto err;
+ }
+ if (ca_prikey == nullptr || rootcsr == nullptr || subcsr == nullptr) {
+ SIGNATURE_TOOLS_LOGE("Sign failed because of ca_prikey, roocsr or subcsr is nullptr\n");
+ goto err;
+ }
+ result = (!X509_set_pubkey(cert, pubKey));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_pubkey failed\n");
+ goto err;
+ }
+ result = (!X509_set_issuer_name(cert, X509_REQ_get_subject_name(rootcsr)));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed\n");
+ X509_NAME_free(X509_REQ_get_subject_name(rootcsr));
+ goto err;
+ }
+ result = (!X509_set_subject_name(cert, X509_REQ_get_subject_name(subcsr)));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed\n");
+ X509_NAME_free(X509_REQ_get_subject_name(subcsr));
+ goto err;
+ }
+ result = (!SignCert(cert, ca_prikey, signAlg));
+ if (result) {
+ goto err;
+ }
+ EVP_PKEY_free(pubKey);
+ return true;
+err:
+ EVP_PKEY_free(pubKey);
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+X509* CertTools::SignCsrGenerateCert(X509_REQ* rootcsr, X509_REQ* subcsr,
+ EVP_PKEY* keyPair, Options* options)
+{
+ bool result = false;
+ X509* cert = X509_new();
+ long serialNumber = 0;
+ int validity = options->GetInt(Options::VALIDITY);
+ result = (!SerialNumberBuilder(&serialNumber) ||
+ !SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert, serialNumber));
+ if (result) {
+ goto err;
+ }
+ result = SetCertValidity(cert, validity);
+ if (!result) {
+ goto err;
+ }
+ result = (!SetBisicConstraintsPatchLen(options, cert) ||
+ !SetKeyIdentifierExt(cert) ||
+ !SetKeyUsage(cert, options) ||
+ !SignForSubCert(cert, subcsr, rootcsr, keyPair, options));
+ if (result) {
+ goto err;
+ }
+ return cert;
+err:
+ X509_free(cert);
+ return nullptr;
+}
+
+bool CertTools::SetSubjectForCert(X509_REQ* certReq, X509* cert)
+{
+ if (certReq == nullptr) {
+ SIGNATURE_TOOLS_LOGE("set subjcet failed because of certReq is nullptr\n");
+ goto err;
+ }
+
+ if (X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed\n");
+ goto err;
+ }
+
+ if (X509_set_issuer_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed\n");
+ goto err;
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+X509* CertTools::GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
+{
+ long serialNumber = 0;
+ bool result = false;
+ X509* cert = X509_new();
+ int validity = options->GetInt(Options::VALIDITY);
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ result = (!SerialNumberBuilder(&serialNumber) ||
+ !SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert, serialNumber));
+ if (result) {
+ goto err;
+ }
+ if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
+ goto err;
+ }
+ result = (!SetBisicConstraintsPatchLen(options, cert) ||
+ !SetSubjectForCert(certReq, cert) ||
+ !SetCertPublickKey(cert, certReq) ||
+ !SetKeyIdentifierExt(cert) ||
+ !SetKeyUsage(cert, options));
+ if (result) {
+ goto err;
+ }
+ result = (!SignCert(cert, keyPair, signAlg));
+ if (result) {
+ goto err;
+ }
+ return cert;
+err:
+ X509_free(cert);
+ return nullptr;
+}
+
+X509* CertTools::GenerateSubCert(EVP_PKEY* keyPair, X509_REQ* rootcsr, Options* options)
+{
+ std::unique_ptr adapter = std::make_unique< LocalizationAdapter>(options);
+ EVP_PKEY* subKey = nullptr;
+ X509_REQ* subcsr = nullptr;
+ X509* subCert = nullptr;
+ subKey = adapter->GetAliasKey(false);
+ if (subKey == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to get the keypair\n");
+ goto err;
+ }
+ subcsr = CertTools::GenerateCsr(subKey, options->GetString(Options::SIGN_ALG),
+ options->GetString(Options::SUBJECT));
+ if (subcsr == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate csr\n");
+ goto err;
+ }
+ subCert = SignCsrGenerateCert(rootcsr, subcsr, keyPair, options);
+ if (subCert == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate the subCert\n");
+ goto err;
+ }
+ EVP_PKEY_free(subKey);
+ X509_REQ_free(subcsr);
+ return subCert;
+err:
+ EVP_PKEY_free(subKey);
+ X509_REQ_free(subcsr);
+ return nullptr;
+}
+
+bool CertTools::SetKeyUsage(X509* cert, Options* options)
+{
+ std::string keyUsage = options->GetString(Options::KEY_USAGE);
+ ASN1_INTEGER* keyUsageInt = ASN1_INTEGER_new();
+ long key_usage = 0;
+ if (keyUsage.empty()) {
+ key_usage = X509v3_KU_KEY_CERT_SIGN | X509v3_KU_CRL_SIGN;
+ if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key_usage)) {
+ SIGNATURE_TOOLS_LOGE("failed to set asn1_integer");
+ ASN1_INTEGER_free(keyUsageInt);
+ return false;
+ }
+ if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, 0, X509V3_ADD_DEFAULT)) {
+ SIGNATURE_TOOLS_LOGE("failed to add ext");
+ ASN1_INTEGER_free(keyUsageInt);
+ return false;
+ }
+ } else {
+ std::vector vecs = StringUtils::SplitString(keyUsage.c_str(), ',');
+ for (auto vec : vecs) {
+ key_usage |= externDic[vec];
+ }
+ if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key_usage)) {
+ SIGNATURE_TOOLS_LOGE("failed to set asn1_integer");
+ ASN1_INTEGER_free(keyUsageInt);
+ return false;
+ }
+ if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, 0, X509V3_ADD_DEFAULT)) {
+ SIGNATURE_TOOLS_LOGE("failed to add ext");
+ ASN1_INTEGER_free(keyUsageInt);
+ return false;
+ }
+ }
+ ASN1_INTEGER_free(keyUsageInt);
+ return true;
+}
+
+bool CertTools::SetkeyUsageExt(X509* cert, Options* options)
+{
+ X509_EXTENSION* ext = nullptr;
+ if (!options->GetString(Options::EXT_KEY_USAGE).empty()) {
+ ext = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(),
+ externKey[options->GetString(Options::EXT_KEY_USAGE)].c_str());
+ if (!ext) {
+ SIGNATURE_TOOLS_LOGE("failed to set extension");
+ X509_EXTENSION_free(ext);
+ return false;
+ }
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("failed to add extension");
+ X509_EXTENSION_free(ext);
+ return false;
+ }
+ }
+ X509_EXTENSION_free(ext);
+ return true;
+}
+
+bool CertTools::SetExpandedInformation(X509* cert, Options* options)
+{
+ bool result = false;
+ result = (!SetKeyUsage(cert, options) ||
+ !SetkeyUsageExt(cert, options));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("Failed to set expanded information \n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetPubkeyAndSignCert(X509* cert, X509_REQ* issuercsr,
+ X509_REQ* certReq, EVP_PKEY* keyPair, Options* options)
+{
+ if (!X509_set_issuer_name(cert, X509_REQ_get_subject_name(issuercsr))) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed\n");
+ goto err;
+ }
+
+ if (!X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq))) {
+ SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed\n");
+ goto err;
+ }
+ if ((options->GetString(Options::SIGN_ALG)) == SIGN_ALG_SHA256) {
+ if (!X509_sign(cert, keyPair, EVP_sha256())) {
+ SIGNATURE_TOOLS_LOGE("X509_sign failed\n");
+ goto err;
+ }
+ } else {
+ if (!X509_sign(cert, keyPair, EVP_sha384())) {
+ SIGNATURE_TOOLS_LOGE("X509_sign failed\n");
+ goto err;
+ }
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+X509* CertTools::GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
+{
+ long serialNumber = 0;
+ int validity = 0;
+ bool result = false;
+ X509_REQ* issuercsr = CertTools::GenerateCsr(keyPair, options->GetString(Options::SIGN_ALG),
+ options->GetString(Options::ISSUER));
+ if (issuercsr == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate the issuercsr\n");
+ return nullptr;
+ }
+
+ X509* cert = X509_new();
+ result = (!SerialNumberBuilder(&serialNumber) ||
+ !SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert, serialNumber) ||
+ !SetKeyIdentifierExt(cert));
+ if (result) {
+ goto err;
+ }
+ validity = options->GetInt(Options::VALIDITY);
+ if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
+ goto err;
+ }
+
+ result = (!SetBisicConstraintsPatchLen(options, cert) ||
+ !SetCertPublickKey(cert, certReq) ||
+ !SetExpandedInformation(cert, options) ||
+ !SetPubkeyAndSignCert(cert, issuercsr, certReq, keyPair, options));
+ if (result) {
+ goto err;
+ }
+ X509_REQ_free(issuercsr);
+ return cert;
+err:
+ X509_free(cert);
+ X509_REQ_free(issuercsr);
+ return nullptr;
+}
+
+X509_REQ* CertTools::GenerateCsr(EVP_PKEY* evpPkey, std::string signAlgorithm, std::string subject)
+{
+ X509_NAME* name = nullptr;
+ X509_REQ* req = X509_REQ_new();
+
+ if (!X509_REQ_set_pubkey(req, evpPkey)) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_set_pubkey failed\n");
+ goto err;
+ }
+
+ name = BuildDN(subject, req);
+ if (!name) {
+ SIGNATURE_TOOLS_LOGE("failed to add subject into cert\n");
+ goto err;
+ }
+
+ if (signAlgorithm == SIGN_ALG_SHA256) {
+ if (!X509_REQ_sign(req, evpPkey, EVP_sha256())) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed\n");
+ goto err;
+ }
+ } else if (signAlgorithm == SIGN_ALG_SHA384) {
+ if (!X509_REQ_sign(req, evpPkey, EVP_sha384())) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed\n");
+ goto err;
+ }
+ } else {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ "Sign algorithm format error! Please check again.");
+ goto err;
+ }
+ return req;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ X509_REQ_free(req);
+ return nullptr;
+}
+
+std::string CertTools::CsrToString(X509_REQ* csr)
+{
+ BIO* csrBio = BIO_new(BIO_s_mem());
+ if (!csrBio) {
+ return "";
+ }
+ if (!PEM_write_bio_X509_REQ(csrBio, csr)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509_REQ error\n");
+ BIO_free(csrBio);
+ return "";
+ }
+ BUF_MEM* data = nullptr;
+ BIO_get_mem_ptr(csrBio, &data);
+ if (!data) {
+ BIO_free(csrBio);
+ return "";
+ }
+ if (!data->data) {
+ BIO_free(csrBio);
+ return "";
+ }
+ std::string csrStr(data->data, data->length);
+ BIO_free(csrBio);
+ return csrStr;
+}
+
+X509* CertTools::ReadfileToX509(const std::string& filename)
+{
+ BIO* certBio = BIO_new_file(filename.c_str(), "rb");
+ if (!certBio) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("BIO_new_file failed\n");
+ BIO_free(certBio);
+ return nullptr;
+ }
+
+ X509* cert = X509_new();
+ if (!PEM_read_bio_X509(certBio, &cert, NULL, NULL)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("PEM_read_bio_X509 failed\n");
+ X509_free(cert);
+ BIO_free(certBio);
+ return nullptr;
+ }
+ BIO_free(certBio);
+
+ return cert;
+}
+
+bool CertTools::SetCertVersion(X509* cert, int versionNum)
+{
+ if (!X509_set_version(cert, versionNum)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set x509 cert version failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertSerialNum(X509* cert, long serialNum)
+{
+ ASN1_INTEGER* ans1Num = nullptr;
+ if (!(ans1Num = X509_get_serialNumber(cert))) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("get x509 cert serial num failed\n");
+ return false;
+ }
+ if (!ASN1_INTEGER_set(ans1Num, serialNum)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set x509 cert serial number failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertIssuerName(X509* cert, X509_NAME* issuer)
+{
+ if (!X509_set_issuer_name(cert, issuer)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set x509 cert issuer name failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertSubjectName(X509* cert, X509_REQ* subjectCsr)
+{
+ X509_NAME* subject = nullptr;
+ if (!(subject = X509_REQ_get_subject_name(subjectCsr))) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("get X509 cert subject name failed\n");
+ return false;
+ }
+ if (!X509_set_subject_name(cert, subject)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set X509 cert subject name failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertValidityStartAndEnd(X509* cert, long vilidityStart, long vilidityEnd)
+{
+ if (!X509_gmtime_adj(X509_getm_notBefore(cert), vilidityStart)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set cert vilidity start time failed\n");
+ return false;
+ }
+ if (!X509_gmtime_adj(X509_getm_notAfter(cert), vilidityEnd)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set cert vilidity end time failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertPublickKey(X509* cert, X509_REQ* subjectCsr)
+{
+ EVP_PKEY* publicKey = X509_REQ_get_pubkey(subjectCsr);
+ if (!publicKey) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("get the pubkey from csr failed\n");
+ return false;
+ }
+ if (!X509_set_pubkey(cert, publicKey)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ EVP_PKEY_free(publicKey);
+ SIGNATURE_TOOLS_LOGE("set public key to cert failed\n");
+ return false;
+ }
+ EVP_PKEY_free(publicKey);
+ return true;
+}
+
+bool CertTools::SetBasicExt(X509* cert)
+{
+ X509_EXTENSION* basicExtension = X509V3_EXT_conf(NULL, NULL, NID_BASIC_CONST.c_str(),
+ DEFAULT_BASIC_EXTENSION.c_str());
+ if (!X509_add_ext(cert, basicExtension, -1)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set basicExtension information failed\n");
+ X509_EXTENSION_free(basicExtension);
+ return false;
+ }
+ X509_EXTENSION_free(basicExtension);
+ return true;
+}
+
+bool CertTools::SetkeyUsageExt(X509* cert)
+{
+ X509_EXTENSION* keyUsageExtension = X509V3_EXT_conf(NULL, NULL, NID_KEYUSAGE_CONST.c_str(),
+ DEFAULT_KEYUSAGE_EXTENSION.c_str());
+ if (!X509_add_ext(cert, keyUsageExtension, -1)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set keyUsageExtension information failed\n");
+ X509_EXTENSION_free(keyUsageExtension);
+ return false;
+ }
+ X509_EXTENSION_free(keyUsageExtension);
+ return true;
+}
+
+bool CertTools::SetKeyUsageEndExt(X509* cert)
+{
+ X509_EXTENSION* keyUsageEndExtension = X509V3_EXT_conf(NULL, NULL, NID_EXT_KEYUSAGE_CONST.c_str(),
+ DEFAULT_EXTEND_KEYUSAGE.c_str());
+ if (!X509_add_ext(cert, keyUsageEndExtension, -1)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set keyUsageEndExtension information failed\n");
+ X509_EXTENSION_free(keyUsageEndExtension);
+ return false;
+ }
+ X509_EXTENSION_free(keyUsageEndExtension);
+ return true;
+}
+
+bool CertTools::SetKeyIdentifierExt(X509* cert)
+{
+ unsigned char digest[SHA256_DIGEST_LENGTH] = {0};
+ unsigned int digestLen = 0;
+ if (X509_pubkey_digest(cert, EVP_sha256(), digest, &digestLen) != 1) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("digest x509 cert public key failed\n");
+ return false;
+ }
+ ASN1_OCTET_STRING* pubKeyDigestData = ASN1_OCTET_STRING_new();
+ if (!ASN1_OCTET_STRING_set(pubKeyDigestData, digest, digestLen)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed\n");
+ ASN1_OCTET_STRING_free(pubKeyDigestData);
+ return false;
+ }
+
+ X509_EXTENSION* subKeyIdentifierExtension = nullptr;
+ /* function OBJ_nid2obj(NID_subject_key_identifier) return value is a global variable, so should not free it */
+ subKeyIdentifierExtension = X509_EXTENSION_create_by_OBJ(NULL, OBJ_nid2obj(NID_subject_key_identifier),
+ 0, pubKeyDigestData);
+ if (!X509_add_ext(cert, subKeyIdentifierExtension, -1)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set subKeyIdentifierExtension information failed\n");
+ ASN1_OCTET_STRING_free(pubKeyDigestData);
+ X509_EXTENSION_free(subKeyIdentifierExtension);
+ return false;
+ }
+ ASN1_OCTET_STRING_free(pubKeyDigestData);
+ X509_EXTENSION_free(subKeyIdentifierExtension);
+ return true;
+}
+
+bool CertTools::SetSignCapacityExt(X509* cert, const char signCapacity[], int capacityLen)
+{
+ ASN1_OCTET_STRING* certSignCapacityData = ASN1_OCTET_STRING_new();
+ if (!ASN1_OCTET_STRING_set(certSignCapacityData, (const unsigned char*)signCapacity, capacityLen)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("failed to set pubkey digst into ASN1 object\n");
+ ASN1_OCTET_STRING_free(certSignCapacityData);
+ return false;
+ }
+ // generate user-define Ni
+ ASN1_OBJECT* nid = OBJ_txt2obj(X509_EXT_OID.c_str(), 1);
+ // generate certSignCapacityData
+ X509_EXTENSION* certSignCapacityExt = X509_EXTENSION_create_by_OBJ(NULL, nid, 0, certSignCapacityData);
+
+ if (!X509_add_ext(cert, certSignCapacityExt, -1)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set certSignCapacityExt information failed\n");
+ ASN1_OBJECT_free(nid);
+ X509_EXTENSION_free(certSignCapacityExt);
+ ASN1_OCTET_STRING_free(certSignCapacityData);
+ return false;
+ }
+ ASN1_OBJECT_free(nid);
+ X509_EXTENSION_free(certSignCapacityExt);
+ ASN1_OCTET_STRING_free(certSignCapacityData);
+ return true;
+}
+
+bool CertTools::SignCert(X509* cert, EVP_PKEY* privateKey, std::string signAlg)
+{
+ const EVP_MD* alg = nullptr;
+ if (signAlg == SIGN_ALG_SHA256) {
+ /* in openssl this func return value is stack variable, so we not need to release it */
+ alg = EVP_sha256();
+ }
+ if (signAlg == SIGN_ALG_SHA384) {
+ alg = EVP_sha384();
+ }
+ if (!X509_sign(cert, privateKey, alg)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("sign X509 cert failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertValidity(X509* cert, int validity)
+{
+ if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SerialNumberBuilder(long* serialNum)
+{
+ unsigned char serialNumber[RANDOM_SERIAL_NUMBER_LENGTH] = {0};
+ if (RAND_bytes(serialNumber, RANDOM_SERIAL_NUMBER_LENGTH) != 1) {
+ SIGNATURE_TOOLS_LOGE("serial number build failed\n");
+ return false;
+ }
+ if (memcpy_s(serialNum, sizeof(long), serialNumber, sizeof(long)) != RET_OK) {
+ SIGNATURE_TOOLS_LOGE("serial number build failed\n");
+ return false;
+ }
+ return true;
+}
+
+X509* CertTools::GenerateEndCert(X509_REQ* csr, EVP_PKEY* issuerKeyPair,
+ LocalizationAdapter& adapter,
+ const char signCapacity[], int capacityLen)
+{
+ X509* cert = X509_new(); // in this function, should not release X509cert memory
+ long serialNumber = 0;
+ X509_REQ* issuerReq = nullptr;
+ bool result = false;
+ do {
+ if (!SerialNumberBuilder(&serialNumber)) { // get ramdom serial number
+ break;
+ }
+ result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || !SetCertSerialNum(cert, serialNumber));
+ if (result) {
+ break;
+ }
+ issuerReq = X509_REQ_new();
+ std::string issuerStr = adapter.options->GetString(adapter.options->ISSUER);
+ result = (!SetCertIssuerName(cert, BuildDN(issuerStr, issuerReq)) || !SetCertSubjectName(cert, csr));
+ if (result) {
+ break;
+ }
+ int validity = adapter.options->GetInt(adapter.options->VALIDITY);
+ result = (!SetCertValidity(cert, validity) || !SetCertPublickKey(cert, csr));
+ if (result) {
+ break;
+ }
+ result = (!SetBasicExt(cert) || !SetkeyUsageExt(cert) || !SetKeyUsageEndExt(cert));
+ if (result) {
+ break;
+ }
+ result = (!SetKeyIdentifierExt(cert) || !SetSignCapacityExt(cert, signCapacity, capacityLen));
+ if (result) {
+ break;
+ }
+ std::string signAlg = adapter.options->GetString(adapter.options->SIGN_ALG);
+ if (!SignCert(cert, issuerKeyPair, signAlg)) {
+ break;
+ }
+
+ adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {}); // release this function use
+ return cert; // return x509 assets
+ } while (0);
+ adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {cert});
+ return nullptr;
+}
+
+} // namespace SignatureTools
+} // namespace OHOS
+
diff --git a/hapsigntool_cpp/services/api/src/localization_adapter.cpp b/hapsigntool_cpp/services/api/src/localization_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..587af9f4d88fa53afb9c4fe2ee86430510d9eae8
--- /dev/null
+++ b/hapsigntool_cpp/services/api/src/localization_adapter.cpp
@@ -0,0 +1,336 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include
+#include
+
+#include "localization_adapter.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+LocalizationAdapter::LocalizationAdapter(Options* options)
+{
+ this->options = options;
+ this->keyStoreHelper = std::make_unique();
+ this->isIssuerKeyStoreFile = false;
+}
+
+int LocalizationAdapter::IsAliasExist(const std::string& alias)
+{
+ std::string keyStoreFile = this->options->GetString(Options::KEY_STORE_FILE);
+ if (!this->keyStoreHelper->IsKeyStoreFileExist(keyStoreFile)) {
+ return RET_FAILED;
+ }
+
+ EVP_PKEY* keyPair = nullptr;
+ char* keyStoreRight = this->options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* keyPwd = this->options->GetChars(Options::KEY_RIGHTS);
+ this->keyStoreHelper->SetIsRegen(true);
+ int status = this->keyStoreHelper->ReadKeyStore(keyStoreFile, keyStoreRight, alias, keyPwd, &keyPair);
+ EVP_PKEY_free(keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ }
+
+ return RET_FAILED;
+}
+
+void LocalizationAdapter::ResetPwd()
+{
+ char* keyRights = this->options->GetChars(Options::KEY_RIGHTS);
+ if (keyRights != nullptr) {
+ ResetChars(keyRights);
+ }
+ char* keyStoreRights = this->options->GetChars(Options::KEY_STORE_RIGHTS);
+ if (keyStoreRights != nullptr) {
+ ResetChars(keyStoreRights);
+ }
+ char* issuerKeyRights = this->options->GetChars(Options::ISSUER_KEY_RIGHTS);
+ if (issuerKeyRights != nullptr) {
+ ResetChars(issuerKeyRights);
+ }
+ char* issuerKeyStoreRights = this->options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
+ if (issuerKeyStoreRights != nullptr) {
+ ResetChars(issuerKeyStoreRights);
+ }
+}
+
+void LocalizationAdapter::ResetChars(char* chars)
+{
+ if (chars == NULL) {
+ return;
+ }
+ for (size_t i = 0; i < strlen(chars); i++) {
+ chars[i] = 0;
+ }
+}
+
+EVP_PKEY* LocalizationAdapter::GetAliasKey(bool autoCreate)
+{
+ EVP_PKEY* keyPair = nullptr;
+ if (this->keyStoreHelper == nullptr) {
+ this->keyStoreHelper = std::make_unique();
+ }
+
+ int status = this->GetKeyPair(autoCreate, &keyPair);
+ if (status == RET_FAILED) {
+ EVP_PKEY_free(keyPair);
+ return nullptr;
+ }
+
+ return keyPair;
+}
+
+int LocalizationAdapter::GetKeyPair(bool autoCreate, EVP_PKEY** keyPair)
+{
+ this->keyStoreHelper->SetPassWordStatus(true);
+ this->keyStoreHelper->SetIsRegen(autoCreate);
+
+ int status = RET_FAILED;
+ if (this->isIssuerKeyStoreFile) {
+ status = this->IssuerKeyStoreFile(keyPair, autoCreate);
+ } else {
+ status = this->KeyStoreFile(keyPair, autoCreate);
+ }
+ this->isIssuerKeyStoreFile = false;
+ return status;
+}
+
+int LocalizationAdapter::KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
+{
+ std::string keyStorePath = "";
+ keyStorePath = this->options->GetString(Options::KEY_STORE_FILE);
+ char* keyStoreRights = this->options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* keyPwd = this->options->GetChars(Options::KEY_RIGHTS);
+ std::string keyAlias = this->options->GetString(Options::KEY_ALIAS);
+ bool fileStatus = this->keyStoreHelper->IsKeyStoreFileExist(keyStorePath);
+ if (fileStatus) {
+ int status = this->keyStoreHelper->ReadKeyStore(keyStorePath, keyStoreRights, keyAlias, keyPwd, keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ } else {
+ if (!this->keyStoreHelper->GetPassWordStatus()) {
+ autoCreate = false;
+ }
+ }
+ }
+ if (autoCreate) {
+ std::string keyAlg = this->options->GetString(Options::KEY_ALG);
+ int keySize = this->options->GetInt(Options::KEY_SIZE);
+ *keyPair = this->keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
+ char* keyStoreRights = this->options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* keyPwd = this->options->GetChars(Options::KEY_RIGHTS);
+ std::string keyAlias = this->options->GetString(Options::KEY_ALIAS);
+ if (keyAlias.empty()) {
+ SIGNATURE_TOOLS_LOGE("Key alias cannot be empty");
+ return RET_FAILED;
+ }
+ int status = this->keyStoreHelper->WriteKeyStore(*keyPair, keyStorePath, keyStoreRights, keyAlias, keyPwd);
+ if (status == RET_OK) {
+ PrintMsg("Remind: generate new keypair ,the keyalias is " + keyAlias + " !");
+ return RET_OK;
+ }
+ }
+
+ return RET_FAILED;
+}
+
+int LocalizationAdapter::IssuerKeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
+{
+ std::string keyStore = this->options->GetString(Options::ISSUER_KEY_STORE_FILE);
+ char* keyStorePwd = this->options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
+ std::string keyAlias = this->options->GetString(Options::ISSUER_KEY_ALIAS);
+ char* keyPairPwd = this->options->GetChars(Options::ISSUER_KEY_RIGHTS);
+
+ if (keyStore.empty()) {
+ keyStore = this->options->GetString(Options::KEY_STORE_FILE);
+ keyStorePwd = this->options->GetChars(Options::KEY_STORE_RIGHTS);
+ }
+
+ bool fileStatus = this->keyStoreHelper->IsKeyStoreFileExist(keyStore);
+ if (fileStatus) {
+ int status = this->keyStoreHelper->ReadKeyStore(keyStore, keyStorePwd, keyAlias, keyPairPwd, keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ } else {
+ if (!this->keyStoreHelper->GetPassWordStatus()) {
+ autoCreate = false;
+ }
+ }
+ }
+
+ if (!fileStatus && !keyStore.empty() && !autoCreate) {
+ PrintErrorNumberMsg("KEY_ALIAS_ERROR", KEY_ALIAS_ERROR, "keyAlias: '"
+ + keyAlias + "' is not exist in" + keyStore);
+ }
+
+ if (autoCreate) {
+ std::string keyAlg = this->options->GetString(Options::KEY_ALG);
+ int keySize = this->options->GetInt(Options::KEY_SIZE);
+ *keyPair = this->keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
+ if (keyStore.empty()) {
+ return this->keyStoreHelper->WriteKeyStore(*keyPair, keyStore, keyStorePwd, keyAlias, keyPairPwd);
+ }
+ }
+
+ return RET_FAILED;
+}
+
+void LocalizationAdapter::SetIssuerKeyStoreFile(bool issuerKeyStoreFile)
+{
+ this->isIssuerKeyStoreFile = issuerKeyStoreFile;
+}
+
+STACK_OF(X509)* LocalizationAdapter::GetSignCertChain()
+{
+ std::string certPath = options->GetString(Options::PROFILE_CERT_FILE);
+ if (certPath.empty()) {
+ certPath = options->GetString(Options::APP_CERT_FILE);
+ }
+ STACK_OF(X509)* certificates = sk_X509_new(NULL);
+ if (certificates == NULL) {
+ SIGNATURE_TOOLS_LOGE("sk_X509_new failed");
+ return NULL;
+ }
+ std::vector certs = this->GetCertsFromFile(certPath, Options::PROFILE_CERT_FILE);
+ if (certs.size() == 0) {
+ return NULL;
+ }
+ for (int i = 0; i < static_cast(certs.size()); i++) {
+ sk_X509_push(certificates, certs[i]);
+ }
+ if (sk_X509_num(certificates) < MIN_CERT_CHAIN_SIZE && sk_X509_num(certificates) > MAX_CERT_CHAIN_SIZE) {
+ SIGNATURE_TOOLS_LOGE("Profile cert '%s' must a cert chain", certPath.c_str());
+ sk_X509_free(certificates);
+ return NULL;
+ }
+ return certificates;
+}
+/********************************************************************************
+* Explain
+*
+* Author: yuanbin
+* time:2024/04/19
+*
+* Funs performance:Get caCert and subCaCert for generate certchain(.pem).
+* get issuerKey Pair to store in CertTools
+*********************************************************************************/
+EVP_PKEY* LocalizationAdapter::GetIssureKeyByAlias()
+{
+ return this->GetAliasKey(false);
+}
+
+bool LocalizationAdapter::IsOutFormChain()
+{
+ std::string checkStr = "certChain";
+ std::string outForm = this->options->GetString(Options::OUT_FORM, checkStr);
+ if (outForm.compare("certChain") == 0) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+X509* LocalizationAdapter::GetSubCaCertFile()
+{
+ std::string certPath = this->options->GetString(Options::SUB_CA_CERT_FILE);
+ return GetCertsFromFile(certPath, Options::SUB_CA_CERT_FILE).at(0);
+}
+
+const std::string LocalizationAdapter::GetSignAlg() const
+{
+ return options->GetString(Options::SIGN_ALG);
+}
+
+X509* LocalizationAdapter::GetCaCertFile()
+{
+ std::string certPath = this->options->GetString(Options::CA_CERT_FILE);
+ return GetCertsFromFile(certPath, Options::CA_CERT_FILE).at(0);
+}
+
+const std::string LocalizationAdapter::GetOutFile()
+{
+ return this->options->GetString(Options::OUT_FILE);
+}
+
+std::vector LocalizationAdapter::GetCertsFromFile(std::string& certPath, const std::string& logTitle)
+{
+ SIGNATURE_TOOLS_LOGD("outPutPath = %{public}s , logTitle = %{public}s", certPath.c_str(), logTitle.c_str());
+ std::vector certs;
+ if (certPath.empty()) {
+ SIGNATURE_TOOLS_LOGE("cert path not exist!");
+ return certs;
+ }
+ // Read And Get Cert
+ BIO* bio = BIO_new_file(certPath.c_str(), "rb");
+ if (!bio) {
+ PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "open file:" + certPath + "failed");
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ BIO_free(bio);
+ return certs;
+ }
+ X509* cert = nullptr;
+ while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != nullptr) {
+ certs.emplace_back(cert);
+ }
+ BIO_free(bio);
+ return certs;
+}
+
+const std::string LocalizationAdapter::GetInFile()
+{
+ return this->options->GetString(Options::IN_FILE);
+}
+
+bool LocalizationAdapter::IsRemoteSigner()
+{
+ std::string defMode = "localSign";
+ std::string destMode = "remoteSign";
+ std::string mode = this->options->GetString(Options::MODE, defMode);
+ return StringUtils::CaseCompare(mode, destMode);
+}
+
+Options* LocalizationAdapter::GetOptions()
+{
+ return options;
+}
+
+void LocalizationAdapter::AppAndProfileAssetsRealse(std::initializer_list keys,
+ std::initializer_list reqs,
+ std::initializer_list certs)
+{
+ for (auto cert : certs) {
+ if (cert) {
+ X509_free(cert);
+ cert = nullptr;
+ }
+ }
+ for (auto req : reqs) {
+ if (req) {
+ X509_REQ_free(req);
+ req = nullptr;
+ }
+ }
+ for (auto key : keys) {
+ if (key) {
+ EVP_PKEY_free(key);
+ key = nullptr;
+ }
+ }
+}
+
+} // namespace SignatureTools
+} // namespace OHOS
+
diff --git a/hapsigntool_cpp/services/api/src/sign_tool_service_impl.cpp b/hapsigntool_cpp/services/api/src/sign_tool_service_impl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6722556b7de3f93a622ec680fffe49ff9c466692
--- /dev/null
+++ b/hapsigntool_cpp/services/api/src/sign_tool_service_impl.cpp
@@ -0,0 +1,702 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sign_tool_service_impl.h"
+#include
+
+#include "pkcs7_data.h"
+#include "profile_sign_tool.h"
+#include "nlohmann/json.hpp"
+#include "profile_info.h"
+#include "profile_verify.h"
+#include "signature_tools_errno.h"
+#include "local_sign_provider.h"
+#include "signature_tools_log.h"
+#include "param_constants.h"
+#include "verify_hap.h"
+#include "constant.h"
+#include "remote_sign_provider.h"
+#include "verify_elf.h"
+#include "verify_bin.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+bool SignToolServiceImpl::GenerateCA(Options* options)
+{
+ bool flag = true;
+ std::unique_ptr adapter = std::make_unique(options);
+ bool isEmpty = FileUtils::IsEmpty(options->GetString(Options::ISSUER_KEY_ALIAS));
+ EVP_PKEY* subKey = adapter->GetAliasKey(true);
+ if (!subKey) {
+ SIGNATURE_TOOLS_LOGE("failed to get subKey!");
+ return false;
+ }
+ EVP_PKEY* rootKey = nullptr;
+ if (isEmpty) {
+ if (HandleIssuerKeyAliasEmpty(options) == RET_FAILED) {
+ EVP_PKEY_free(subKey);
+ return false;
+ }
+ flag = GenerateRootCertToFile(options, subKey);
+ EVP_PKEY_free(subKey);
+ } else {
+ if (HandleIsserKeyAliasNotEmpty(options) == RET_FAILED) {
+ EVP_PKEY_free(subKey);
+ return false;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ rootKey = adapter->GetAliasKey(false);
+ flag = GenerateSubCertToFile(options, rootKey);
+ EVP_PKEY_free(rootKey);
+ EVP_PKEY_free(subKey);
+ }
+ adapter->ResetPwd();
+ return flag;
+}
+
+bool SignToolServiceImpl::GenerateRootCertToFile(Options* options, EVP_PKEY* rootKey)
+{
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ std::string subject = options->GetString(Options::SUBJECT);
+ std::string outFile;
+ X509* cert = nullptr;
+ X509_REQ* csr = nullptr;
+ bool result = false;
+ if (rootKey == nullptr) {
+ goto err;
+ }
+ csr = CertTools::GenerateCsr(rootKey, signAlg, subject);
+ if (!csr) {
+ goto err;
+ }
+ cert = CertTools::GenerateRootCertificate(rootKey, csr, options);
+ if (!cert) {
+ goto err;
+ }
+ if (!X509CertVerify(cert, rootKey)) {
+ goto err;
+ }
+
+ if (!OutputModeOfCert(cert, options)) {
+ goto err;
+ }
+ result = true;
+err:
+ if (result == false)
+ SIGNATURE_TOOLS_LOGE("generate root cert failed!\n");
+ X509_free(cert);
+ X509_REQ_free(csr);
+ return result;
+}
+
+bool SignToolServiceImpl::GenerateSubCertToFile(Options* options, EVP_PKEY* rootKey)
+{
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ std::string issuer = options->GetString(Options::ISSUER);
+ X509* cert = nullptr;
+ X509_REQ* csr = nullptr;
+ bool result = false;
+ if (rootKey == nullptr) {
+ goto err;
+ }
+ csr = CertTools::GenerateCsr(rootKey, signAlg, issuer);
+ if (!csr) {
+ goto err;
+ }
+ cert = CertTools::GenerateSubCert(rootKey, csr, options);
+ if (!cert) {
+ goto err;
+ }
+ if (!X509CertVerify(cert, rootKey)) {
+ goto err;
+ }
+ if (!OutputModeOfCert(cert, options)) {
+ goto err;
+ }
+ result = true;
+err:
+ if (result == false)
+ SIGNATURE_TOOLS_LOGE("generate sub cert failed!\n");
+ X509_free(cert);
+ X509_REQ_free(csr);
+ return result;
+}
+
+int SignToolServiceImpl::HandleIssuerKeyAliasEmpty(Options* options)
+{
+ std::string iksFile = options->GetString(Options::ISSUER_KEY_STORE_FILE);
+ if (!FileUtils::IsEmpty(iksFile) && !options->Equals(Options::KEY_STORE_FILE, Options::ISSUER_KEY_STORE_FILE)) {
+ PrintErrorNumberMsg("WRITE_FILE_ERROR", IO_ERROR,
+ "Parameter '" + iksFile + "' and parameter '" +
+ options->GetString(Options::KEY_STORE_FILE) + "' are inconsistent");
+ return RET_FAILED;
+ }
+ char* keyStoreRights = options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* issuerKeyStoreRights = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
+ if (!FileUtils::IsEmpty(iksFile)) {
+ if ((keyStoreRights == nullptr && issuerKeyStoreRights != nullptr) ||
+ (keyStoreRights != nullptr && issuerKeyStoreRights == nullptr)) {
+ goto err;
+ } else if (keyStoreRights == nullptr && issuerKeyStoreRights == nullptr) {
+ return RET_OK;
+ } else {
+ if (std::strcmp(keyStoreRights, issuerKeyStoreRights) != 0) {
+ goto err;
+ }
+ }
+ }
+ return RET_OK;
+err:
+ PrintErrorNumberMsg("WRITE_FILE_ERROR", IO_ERROR,
+ "Parameter 'keystorePwd' and parameter 'issuerKeystorePwd' are inconsistent");
+ return RET_FAILED;
+}
+
+int SignToolServiceImpl::HandleIsserKeyAliasNotEmpty(Options* options)
+{
+ std::string iksFile = options->GetString(Options::ISSUER_KEY_STORE_FILE);
+ if (!FileUtils::IsEmpty(iksFile)) {
+ if (!FileUtils::ValidFileType(iksFile, {"p12", "jks"})) {
+ SIGNATURE_TOOLS_LOGE("issuer keystore file type is inconsistent!");
+ return RET_FAILED;
+ }
+ }
+ return RET_OK;
+}
+
+bool SignToolServiceImpl::OutputModeOfCert(X509* cert, Options* options)
+{
+ std::string outFile = options->GetString(Options::OUT_FILE);
+ if (!outFile.empty()) {
+ if (!CertTools::SaveCertTofile(outFile, cert)) {
+ PrintErrorNumberMsg("WRITE_FILE_ERROR", IO_ERROR, "failed to save cert to file");
+ return false;
+ }
+ } else {
+ if (!PrintX509CertFromMemory(cert)) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::GenerateCert(Options* options)
+{
+ std::unique_ptr adapter = std::make_unique(options);
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ std::string subject = options->GetString(Options::SUBJECT);
+ EVP_PKEY* subjectkeyPair = nullptr;
+ EVP_PKEY* rootKeyPair = nullptr;
+ X509_REQ* csr = nullptr;
+ X509* cert = nullptr;
+ bool result = false;
+ subjectkeyPair = adapter->GetAliasKey(false);
+ if (!subjectkeyPair) {
+ goto err;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ rootKeyPair = adapter->GetIssureKeyByAlias();
+ if (!rootKeyPair) {
+ goto err;
+ }
+ adapter->ResetPwd();
+ csr = CertTools::GenerateCsr(subjectkeyPair, signAlg, subject);
+ if (!csr) {
+ goto err;
+ }
+ cert = CertTools::GenerateCert(rootKeyPair, csr, options);
+ if (!cert) {
+ goto err;
+ }
+ if (!X509CertVerify(cert, rootKeyPair)) {
+ goto err;
+ }
+ if (!OutputModeOfCert(cert, options)) {
+ goto err;
+ }
+ result = true;
+err:
+ if (result == false)
+ SIGNATURE_TOOLS_LOGE("generate cert failed!\n");
+ X509_free(cert);
+ X509_REQ_free(csr);
+ EVP_PKEY_free(rootKeyPair);
+ EVP_PKEY_free(subjectkeyPair);
+ return result;
+}
+
+bool SignToolServiceImpl::GenerateKeyStore(Options* options)
+{
+ std::unique_ptr adaptePtr = std::make_unique(options);
+ std::string keyAlias = adaptePtr->options->GetString(Options::KEY_ALIAS);
+
+ int status = adaptePtr->IsAliasExist(keyAlias);
+ if (status == RET_OK) {
+ adaptePtr->ResetPwd();
+ PrintErrorNumberMsg("KEY_ALIAS_ERROR", KEY_ALIAS_ERROR, "'" + keyAlias
+ + "' key alias already exists and cannot be generated repeatedly");
+ return false;
+ }
+
+ if (!adaptePtr->keyStoreHelper->GetPassWordStatus()) {
+ adaptePtr->ResetPwd();
+ return false;
+ }
+
+ EVP_PKEY* keyPair = nullptr;
+ keyPair = adaptePtr->GetAliasKey(true);
+ adaptePtr->ResetPwd();
+ if (keyPair == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to get keypair!");
+ return false;
+ }
+ EVP_PKEY_free(keyPair);
+ return true;
+}
+
+bool SignToolServiceImpl::GenerateCsr(Options* options)
+{
+ std::unique_ptr adapter = std::make_unique(options);
+ EVP_PKEY* keyPair = adapter->GetAliasKey(false);
+ if (!keyPair) {
+ SIGNATURE_TOOLS_LOGE("failed to get keypair!");
+ adapter->ResetPwd();
+ return false;
+ }
+ adapter->ResetPwd();
+ X509_REQ* csr = nullptr;
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ std::string subject = options->GetString(Options::SUBJECT);
+ if (signAlg.empty()) {
+ PrintErrorNumberMsg("INVALIDPARAM_ERROR",
+ INVALIDPARAM_ERROR,
+ "Please check if signalg has been specified which is required.");
+ return false;
+ }
+ if (subject.empty()) {
+ PrintErrorNumberMsg("INVALIDPARAM_ERROR",
+ INVALIDPARAM_ERROR,
+ "Please check if subject has been specified which is required.");
+ return false;
+ }
+ csr = CertTools::GenerateCsr(keyPair, signAlg, subject);
+ if (!csr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate csr request!");
+ EVP_PKEY_free(keyPair);
+ return false;
+ }
+ std::string csrStr = CertTools::CsrToString(csr);
+ EVP_PKEY_free(keyPair);
+ X509_REQ_free(csr);
+ if (csrStr.size() == 0) {
+ PrintErrorNumberMsg("PARSE_ERROR", PARSE_ERROR,
+ "failed to transform csr to string!");
+ return false;
+ }
+ std::string outFile = options->GetString(Options::OUT_FILE);
+ return OutputString(csrStr, outFile);
+}
+
+bool SignToolServiceImpl::OutputString(std::string content, std::string file)
+{
+ if (file.size() == 0) {
+ puts(content.c_str());
+ return true;
+ }
+ std::ofstream outFile(file.c_str());
+ if (!outFile.is_open()) {
+ PrintErrorNumberMsg("IO_ERROR", IO_ERROR,
+ "failed to open the outFile " + file + " !");
+ return false;
+ }
+ outFile << content;
+ outFile.close();
+ return true;
+}
+
+bool SignToolServiceImpl::X509CertVerify(X509* cert, EVP_PKEY* privateKey)
+{
+ if (!X509_verify(cert, privateKey)) {
+ PrintErrorNumberMsg("VERIFY_ERROR", VERIFY_ERROR, "private key verify cert failed!");
+ return false;
+ }
+ return true;
+}
+
+X509_REQ* SignToolServiceImpl::GetCsr(EVP_PKEY* keyPair, std::string signAlg, std::string subject)
+{
+ if (signAlg.empty() || subject.empty()) {
+ SIGNATURE_TOOLS_LOGE("failed to get signalg or subject!");
+ return nullptr;
+ }
+ X509_REQ* csr = CertTools::GenerateCsr(keyPair, signAlg, subject);
+ if (!csr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate csr!");
+ return nullptr;
+ }
+ return csr;
+}
+
+bool SignToolServiceImpl::GenerateAppCert(Options* options)
+{
+ std::unique_ptr adapter = std::make_unique(options);
+ EVP_PKEY* keyPair = nullptr;
+ EVP_PKEY* issueKeyPair = nullptr;
+ X509_REQ* csr = nullptr;
+ X509* x509Certificate = nullptr;
+ std::string signAlg = adapter->options->GetString(Options::SIGN_ALG);
+ std::string subject = adapter->options->GetString(Options::SUBJECT);
+ do {
+ if (!(keyPair = adapter->GetAliasKey(false))) { // get keypair
+ break;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ if (!(issueKeyPair = adapter->GetIssureKeyByAlias())) { // get issuer keypair
+ break;
+ }
+ adapter->ResetPwd(); // clean pwd for safety
+ csr = GetCsr(keyPair, signAlg, subject);
+ if (!csr) { // get CSR request
+ break;
+ }
+ x509Certificate = CertTools::GenerateEndCert(csr, issueKeyPair, *adapter,
+ APP_SIGNING_CAPABILITY,
+ sizeof(PROFILE_SIGNING_CAPABILITY)); // get app x509 cert
+ if (!x509Certificate) {
+ PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, "generate app cert failed");
+ break;
+ }
+
+ if (!X509CertVerify(x509Certificate, issueKeyPair)) {
+ break;
+ }
+
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {}); // realse heap memory
+ return GetAndOutPutCert(*adapter, x509Certificate); // output cert to file
+ } while (0);
+
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {x509Certificate});
+ return false;
+}
+
+bool SignToolServiceImpl::GenerateProfileCert(Options* options)
+{
+ std::unique_ptr adapter = std::make_unique(options);
+ EVP_PKEY* keyPair = nullptr;
+ EVP_PKEY* issueKeyPair = nullptr;
+ X509_REQ* csr = nullptr;
+ X509* x509Certificate = nullptr;
+ std::string signAlg = adapter->options->GetString(Options::SIGN_ALG);
+ std::string subject = adapter->options->GetString(Options::SUBJECT);
+
+ do {
+ if (!(keyPair = adapter->GetAliasKey(false))) { // get keypair
+ break;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ if (!(issueKeyPair = adapter->GetIssureKeyByAlias())) { // get issuer keypair
+ break;
+ }
+ adapter->ResetPwd(); // clean pwd for safety
+ if (!(csr = GetCsr(keyPair, signAlg, subject))) { // get CSR request
+ break;
+ }
+ x509Certificate = CertTools::GenerateEndCert(csr, issueKeyPair, *adapter,
+ PROFILE_SIGNING_CAPABILITY,
+ sizeof(PROFILE_SIGNING_CAPABILITY)); // get profile x509 cert
+ if (!x509Certificate) {
+ SIGNATURE_TOOLS_LOGE("failed generate x509 cert");
+ break;
+ }
+ if (!X509CertVerify(x509Certificate, issueKeyPair)) {
+ break;
+ }
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {}); // realse assets
+ return GetAndOutPutCert(*adapter, x509Certificate); // output cert to file
+ } while (0);
+
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {x509Certificate});
+ return false;
+}
+
+bool SignToolServiceImpl::GetAndOutPutCert(LocalizationAdapter& adapter, X509* cert)
+{
+ std::string outFile = adapter.options->GetString(Options::OUT_FILE);
+ bool successflag = false;
+ X509* subCaCert = nullptr;
+ X509* rootCaCert = nullptr;
+ std::vector certificates;
+ if (adapter.IsOutFormChain()) {
+ certificates.emplace_back(cert); // add root cert
+ // add sub and ca cert
+ successflag = (!(subCaCert = adapter.GetSubCaCertFile()) ||
+ !(rootCaCert = adapter.GetCaCertFile()));
+ if (successflag) {
+ return false;
+ }
+ certificates.emplace_back(subCaCert);
+ certificates.emplace_back(rootCaCert);
+
+ if (outFile.empty()) { // print certchain to cmd
+ successflag = PrintX509CertChainFromMemory(certificates);
+ for (auto cert : certificates) {
+ X509_free(cert);
+ }
+ return successflag;
+ }
+
+ return OutPutCertChain(certificates, adapter.GetOutFile());
+ }
+ if (outFile.empty()) { // print cert to cmd
+ successflag = PrintX509CertFromMemory(cert);
+ X509_free(cert);
+ return successflag;
+ }
+
+ return OutPutCert(cert, adapter.GetOutFile());
+}
+
+bool SignToolServiceImpl::SignProfile(Options* options)
+{
+ LocalizationAdapter adapter(options);
+ const std::string inFile = adapter.GetInFile();
+ const std::string outFile = adapter.GetOutFile();
+ std::string provisionContent;
+ std::string p7b;
+ if (SignToolServiceImpl::GetProvisionContent(inFile, provisionContent) < 0) {
+ SIGNATURE_TOOLS_LOGE("getProvisionContent failed\n");
+ return false;
+ }
+ if (ProfileSignTool::GenerateP7b(adapter, provisionContent, p7b) < 0) {
+ SIGNATURE_TOOLS_LOGE("generate P7b data failed\n");
+ return false;
+ }
+ if (FileUtils::Write(p7b, outFile) < 0) {
+ SIGNATURE_TOOLS_LOGE("write p7b data failed\n");
+ return false;
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::SignHap(Options* options)
+{
+ std::string mode = options->GetString(Options::MODE);
+ std::shared_ptr signProvider;
+ if ("localSign" == mode) {
+ signProvider = std::make_shared();
+ } else if ("remoteSign" == mode) {
+ signProvider = std::make_shared();
+ } else {
+ SIGNATURE_TOOLS_LOGE("Resign mode. But not implemented yet");
+ return false;
+ }
+ std::string inForm = options->GetString(Options::INFORM);
+ if (ZIP == inForm) {
+ return signProvider->Sign(options);
+ } else if (ELF == inForm) {
+ return signProvider->SignElf(options);
+ } else {
+ return signProvider->SignBin(options);
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::VerifyProfile(Options* options)
+{
+ LocalizationAdapter adapter(options);
+ std::string p7b;
+ if (FileUtils::ReadFile(adapter.GetInFile(), p7b) < 0) {
+ SIGNATURE_TOOLS_LOGE("read p7b data error\n");
+ return false;
+ }
+ PKCS7Data p7Data;
+ if (p7Data.Parse(p7b) < 0) {
+ SIGNATURE_TOOLS_LOGE("verify profile failed\n");
+ return false;
+ }
+ if (p7Data.Verify() < 0) {
+ SIGNATURE_TOOLS_LOGE("verify profile failed\n");
+ return false;
+ }
+ const std::string outFile = adapter.GetOutFile();
+ std::string originalData;
+ if (p7Data.GetContent(originalData) < 0) {
+ SIGNATURE_TOOLS_LOGE("get content failed\n");
+ return false;
+ }
+ if (outFile.empty()) {
+ PrintMsg(originalData);
+ } else {
+ std::ofstream out(outFile, std::ios::binary);
+ out.write(originalData.data(), originalData.size());
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::OutPutCertChain(std::vector& certs, const std::string& outPutPath)
+{
+ SIGNATURE_TOOLS_LOGD("outPutPath = %{public}s", outPutPath.c_str());
+ BIO* bio = nullptr;
+ if (!(bio = BIO_new_file(outPutPath.c_str(), "wb"))) {
+ SIGNATURE_TOOLS_LOGE("failed to open file");
+ goto err;
+ }
+ for (auto cert : certs) {
+ if (PEM_write_bio_X509(bio, cert) < 0) {
+ SIGNATURE_TOOLS_LOGE("failed to write certChain to file!");
+ goto err;
+ }
+ }
+ BIO_free(bio);
+ for (auto cert : certs) {
+ X509_free(cert);
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ BIO_free(bio);
+ for (auto& cert : certs) {
+ X509_free(cert);
+ }
+ return false;
+}
+
+bool SignToolServiceImpl::OutPutCert(X509* certs, const std::string& outPutPath)
+{
+ SIGNATURE_TOOLS_LOGE("outPutPath = %{public}s", outPutPath.c_str());
+ BIO* bio = BIO_new_file(outPutPath.c_str(), "wb");
+ if (!bio) {
+ SIGNATURE_TOOLS_LOGE("failed to open file");
+ goto err;
+ }
+ if (!PEM_write_bio_X509(bio, certs)) {
+ SIGNATURE_TOOLS_LOGE("failed to write cert to file!");
+ goto err;
+ }
+ X509_free(certs);
+ BIO_free(bio);
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ X509_free(certs);
+ BIO_free(bio);
+ return false;
+}
+
+int SignToolServiceImpl::GetProvisionContent(const std::string& input, std::string& ret)
+{
+ std::string bytes;
+ if (FileUtils::ReadFile(input, bytes) < 0) {
+ SIGNATURE_TOOLS_LOGE("provision read faild!\n");
+ return IO_ERROR;
+ }
+ nlohmann::json obj = nlohmann::json::parse(bytes);
+ if (obj.is_discarded() || (!obj.is_structured())) {
+ SIGNATURE_TOOLS_LOGE("Parsing appProvision failed!");
+ PrintErrorNumberMsg("PARSE ERROR", PARSE_ERROR, "Parsing appProvision failed!");
+ return PARSE_ERROR;
+ }
+ ret = obj.dump();
+ ProfileInfo provision;
+ AppProvisionVerifyResult result = ParseProvision(ret, provision);
+ if (result != PROVISION_OK) {
+ SIGNATURE_TOOLS_LOGE("invalid provision\n");
+ return INVALIDPARAM_ERROR;
+ }
+ return 0;
+}
+
+bool SignToolServiceImpl::PrintX509CertFromMemory(X509* cert)
+{
+ BIO* bio = BIO_new(BIO_s_mem());
+ if (!bio) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ if (PEM_write_bio_X509(bio, cert) == 1) {
+ BUF_MEM* bptr;
+ BIO_get_mem_ptr(bio, &bptr);
+ PrintMsg(std::string(bptr->data, bptr->length));
+ } else {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "print x509 cert falied");
+ BIO_free(bio);
+ return false;
+ }
+ BIO_free(bio);
+ return true;
+}
+
+bool SignToolServiceImpl::PrintX509CertChainFromMemory(std::vector certs)
+{
+ for (auto cert : certs) {
+ BIO* bio = BIO_new(BIO_s_mem());
+ BUF_MEM* bptr = nullptr;
+ if (!bio) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ if (PEM_write_bio_X509(bio, cert) == 1) {
+ BIO_get_mem_ptr(bio, &bptr);
+ PrintMsg(std::string(bptr->data, bptr->length));
+ } else {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "print x509 cert falied");
+ BIO_free(bio);
+ return false;
+ }
+ BIO_free(bio);
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::VerifyHapSigner(Options* option)
+{
+ std::string inForm = option->GetString(ParamConstants::PARAM_IN_FORM);
+ if (inForm == ZIP) {
+ HapVerifyResult hapVerifyResult;
+ VerifyHap hapVerifyV2;
+ int32_t ret = hapVerifyV2.Verify(option->GetString(Options::IN_FILE), hapVerifyResult, option);
+ if (ret == VERIFY_SUCCESS) {
+ PrintMsg("hap verify successed!");
+ return true;
+ }
+ PrintMsg("hap verify failed !");
+ return false;
+ } else if (inForm == ELF) {
+ VerifyElf verifyElf;
+ if (!verifyElf.Verify(option)) {
+ PrintMsg("elf verify failed!");
+ return false;
+ }
+ PrintMsg("elf verify successed!");
+ return true;
+ } else if (inForm == BIN) {
+ VerifyBin verifyBin;
+ if (!verifyBin.Verify(option)) {
+ PrintMsg("bin verify failed!");
+ return false;
+ }
+ PrintMsg("bin verify successed!");
+ return true;
+ } else {
+ PrintErrorNumberMsg("NOT_SUPPORT_ERROR", NOT_SUPPORT_ERROR, "This requirement was not implemented !");
+ return false;
+ }
+}
+
+} // namespace SignatureTools
+} // namespace OHOS
diff --git a/hapsigntool_cpp/services/cmd/include/cmd_util.h b/hapsigntool_cpp/services/cmd/include/cmd_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a6c1f4944d36ea4d36484f3145ae65114ec6c70
--- /dev/null
+++ b/hapsigntool_cpp/services/cmd/include/cmd_util.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNATRUETOOLS_CMD_UTIL_H
+#define SIGNATRUETOOLS_CMD_UTIL_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "params.h"
+#include "params_trust_list.h"
+#include "sign_tool_service_impl.h"
+#include "signature_tools_log.h"
+#include "verify_hap_openssl_utils.h"
+
+namespace OHOS {
+namespace SignatureTools {
+class CmdUtil final {
+public:
+ CmdUtil() = default;
+ bool Convert2Params(char** args, size_t size, ParamsSharedPtr param);
+ static bool JudgeAlgType(std::string keyAlg);
+ static bool JudgeSize(int size);
+ static bool JudgeSignAlgType(std::string signAlg);
+ static bool JudgeEndSignAlgType(std::string signAlg);
+ static bool VerifyType(std::string inputType);
+ static bool VerifyTypes(std::string inputType);
+ static bool VerifyType(std::string inputtype, std::string supportTypes);
+ static constexpr int ARGS_MIN_LEN = 2;
+
+private:
+ int GetCommandParameterKey(char strChar, std::string& strChars,
+ std::vector& trustList, std::string& keyStandBy);
+ bool ValidAndPutParam(ParamsSharedPtr params, const std::string& key, char* value);
+ static const std::regex INTEGER_PATTERN;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif
diff --git a/hapsigntool_cpp/services/cmd/include/help.h b/hapsigntool_cpp/services/cmd/include/help.h
new file mode 100644
index 0000000000000000000000000000000000000000..43aaeee2b2ffd4ce6f465c3fab6f50953072b269
--- /dev/null
+++ b/hapsigntool_cpp/services/cmd/include/help.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef HELP_H
+#define HELP_H
+
+#include
+ /* this file use to create help.txt content and
+ * it is divided into 12 strings according
+ * to the functional module
+ */
+namespace OHOS {
+namespace SignatureTools {
+
+const std::string HELP_TXT_HEADER = R"(
+USAGE: [options]
+USAGE: [options]
+)";
+
+const std::string KEYPAIR_HELP_TXT = R"(
+ generate-keypair[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -keyAlg : key algorithm, required fields, including ECC;
+ -keySize : key size, required fields, and the size of the ECC algorithm is NIST-P-256/NIST-P-384;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -extCfgFile : Extend Profile, optional fields;
+
+ EXAMPLE:
+ generate-keypair -keyAlias "oh-app1-key-v1" -keyPwd ****** -keyAlg ECC -keySize NIST-P-256
+-keystoreFile "/home/app-keypair.jks" -keystorePwd ******
+ generate-keypair -keyAlias "oh-profile-key-v1" -keyPwd ****** -keyAlg ECC -keySize NIST-P-256
+-keystoreFile "/home/profile-keypair.jks" -keystorePwd ******
+)";
+
+const std::string CSR_HELP_TXT = R"(
+ generate-csr[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -subject : certificate subject, required fields;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outFile : output file, optional fields, if not filled, it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+
+ EXAMPLE:
+ generate-csr -keyAlias "oh-app1-key-v1" -keyPwd ****** -signAlg SHA256withECDSA -keystorePwd ******
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=App1 Release" -keystoreFile "/home/app-keypair.jks"
+-outFile "/home/oh-app1-key-v1.csr"
+)";
+
+const std::string CERT_HELP_TXT = R"(
+ generate-cert[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -issuer : issuer subject, required fields;
+ -issuerKeyAlias : issuer key alias, required fields;
+ -issuerKeyPwd : issuer key password, optional fields;
+ -subject : certificate subject, required fields;
+ -validity : certificate validity, optional fields, the default is 1095 days;
+ -keyUsage : key usage, required fields, including digitalSignature, nonRepudiation, keyEncipherment,
+ dataEncipherment, keyAgreement, certificateSignature, crlSignature, encipherOnly and decipherOnly, if the
+ certificate includes multiple key usages, separate them with commas;
+ -keyUsageCritical : whether keyUsage is a key item, optional fields, the default is true;
+ -extKeyUsage : extended key usage, optional fields, including clientAuthentication, serverAuthentication,
+ codeSignature, emailProtection, smartCardLogin, timestamp, ocspSignature;
+ -extKeyUsageCritical : whether extKeyUsage is a key item, optional fields, the default is false;
+ -signAlg : signature algorithm, required fields, includingSHA256withECDSA/SHA384withECDSA;
+ -basicConstraints : whether to include basicConstraints, optional fields, the default is false;
+ -basicConstraintsCritical : whether basicConstraints is a key item, optional fields, the default is false;
+ -basicConstraintsCa : whether it is CA, optional fields, the default is false;
+ -basicConstraintsPathLen : basicConstraints path length, optional fields, the default is 0;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outFile : output file, optional fields, if not filled, it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+ -issuerKeystoreFile : issuer keystore file, optional fields, JKS or P12 format;
+ -issuerKeystorePwd : issuer keystore password, optional fields;
+
+ EXAMPLE:
+ generate-cert -keyAlias "oh-app1-key-v1" -keyPwd ****** -issuerKeyAlias "oh-app-sign-srv-ca-key-v1"
+-issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Application Signature Service CA" -issuerKeyPwd ******
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=App1 Release" -outFile "/home/app1.cer" -keystorePwd ******
+-keyUsage digitalSignature -extKeyUsage codeSignature -signAlg SHA256withECDSA -keystoreFile "/home/app-keypair.jks"
+)";
+
+const std::string CA_CERT_HELP_TXT = R"(
+ generate-ca[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -keyAlg : key algorithm, required fields, including ECC;
+ -keySize : key size, required fields, and the size of the ECC algorithm is NIST-P-256/NIST-P-384;
+ -issuer : issuer subject, optional fields, if it is empty, it means root CA;
+ -issuerKeyAlias : issuer key alias, optional fields, if it is empty, it means root CA;
+ -issuerKeyPwd : issuer key password, optional fields;
+ -subject : certificate subject, required fields;
+ -validity : certificate validity, optional fields, the default is 3650 days;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -basicConstraintsPathLen : basicConstraints path length, optional fields, the default is 0;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outFile : output file, optional fields, if not filled, it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+ -issuerKeystoreFile : issuer keystore file, optional fields, JKS or P12 format;
+ -issuerKeystorePwd : issuer keystore password, optional fields;
+
+ EXAMPLE:
+ generate-ca -keyAlias "oh-root-ca-key-v1" -validity 365 -signAlg SHA384withECDSA -keySize NIST-P-256
+ -subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community,CN=Root CA" -keystoreFile "/home/app-keypair.jks"
+ -keystorePwd ****** -outFile "/home/root-ca.cer" -keyAlg ECC
+ generate-ca -keyAlias "oh-app1-key-v1" -keyAlg ECC -issuerKeyAlias "oh-sub-app-ca-key-v1" -issuerKeyPwd ******
+ -issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Root CA" -keySize NIST-P-256 -validity 365
+ -subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN= Application Signature Service CA" -signAlg SHA384withECDSA
+ -keystoreFile "/home/app-keypair.jks" -keystorePwd ****** -outFile "/home/sub-app-sign-srv-ca.cer"
+)";
+
+const std::string APP_CERT_HELP_TXT = R"(
+ generate-app-cert[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -issuer : issuer subject, required fields;
+ -issuerKeyAlias : issuer key alias, required fields;
+ -issuerKeyPwd : issuer key password, optional fields;
+ -subject : certificate subject, required fields;
+ -validity : certificate validity, optional fields, the default is 1095 days;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outForm : the format of the output certificate file, including cert/certChain, optional fields,
+ the default is cert;
+ -rootCaCertFile : root CA certificate file, required when outForm is certChain;
+ -subCaCertFile : secondary sub -CA certificate file, required when outForm is certChain;
+ -outFile : output certificate file(certificate or certificate chain), optional fields, if not filled,
+ it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+ -issuerKeystoreFile : issuer keystore file, optional fields, JKS or P12 format;
+ -issuerKeystorePwd : issuer keystore password, optional fields;
+
+ EXAMPLE:
+ generate-app-cert -keyAlias "oh-app1-key-v1" -issuerKeyAlias "oh-app-sign-debug-srv-ca-key-v1" -validity 365
+-issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Application Debug Signature Service CA" -keyPwd ******
+-signAlg SHA256withECDSA -keystoreFile "/home/app-keypair.jks" -outFile "/home/app-debug-cert.cer" -outForm cert
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=App1 Debug" -keystorePwd ******
+ generate-app-cert -keyAlias "oh-app1-key-v1" -issuerKeyAlias "oh-app-sign-release-srv-ca-key-v1" -validity 365
+-issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Application Release Signature Service CA" -keyPwd ******
+-signAlg SHA256withECDSA -rootCaCertFile "/home/root-ca.cer" -subCaCertFile "/home/sub-app-sign-srv-ca.cer"
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=App1 Release" -keystorePwd ****** -outForm certChain
+-keystoreFile "/home/app-keypair.jks" -outFile "/home/app-release-cert.cer"
+)";
+
+const std::string PROFILE_CERT_HELP_TXT = R"(
+ generate-profile-cert[options]:
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -issuer : issuer subject, required fields;
+ -issuerKeyAlias : issuer key alias, required fields;
+ -issuerKeyPwd : issuer key password, optional fields;
+ -subject : certificate subject, required fields;
+ -validity : certificate validity, optional fields, the default is 1095 days;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -keystoreFile : keystore file, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outForm : the format of the output certificate file, including cert/certChain, optional fields,
+ the default is cert;
+ -rootCaCertFile : root CA certificate file, required when outForm is certChain;
+ -subCaCertFile : secondary sub -CA certificate file, required when outForm is certChain;
+ -outFile : output file, optional fields, if not filled, it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+ -issuerKeystoreFile : issuer keystore file, optional fields, JKS or P12 format;
+ -issuerKeystorePwd : issuer keystore password, optional fields;
+
+ EXAMPLE:
+ generate-profile-cert -keyAlias "oh-profile-key-v1" -issuerKeyAlias "oh-profile-sign-debug-srv-ca-key-v1"
+-keyPwd ****** -issuerKeyPwd ****** -keystoreFile "/home/profile-keypair.jks" -keystorePwd ****** -validity 365
+-issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Provision Profile Debug Signature Service CA"
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Provision Profile Debug" -signAlg SHA256withECDSA
+-outFile "/home/provision-profile-debug.cer" -outForm cert
+ generate-profile-cert -keyAlias "oh-profile-key-v1" -issuerKeyAlias "oh-profile-sign-release-srv-ca-key-v1"
+-keyPwd ****** -issuerKeyPwd ****** -keystoreFile "/home/profile-keypair.jks" -keystorePwd ****** -validity 365
+-issuer "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Provision Profile Release Signature Service CA"
+-subject "C=CN, O=OpenHarmony, OU=OpenHarmony Community, CN=Provision Profile Release" -signAlg SHA256withECDSA
+-rootCaCertFile "/home/root-ca.cer" -subCaCertFile "/home/sub-profile-sign-srv-ca.cer" -outForm certChain
+-outFile "/home/provision-profile-release.cer"
+)";
+
+
+const std::string SIGN_PROFILE_HELP_TXT = R"(
+ sign-profile[options]:
+ -mode : signature mode, required fields, including localSign/remoteSign;
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields;
+ -profileCertFile : profile signing certificate(certificate chain, the order is three -level -two -root),
+ required fields;
+ -inFile : input original Provision Profile file, required fields;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -keystoreFile : keystore file, if signature mode is localSign, required fields, JKS or P12 format;
+ -keystorePwd : keystore password, optional fields;
+ -outFile : output the signed Provision Profile file, p7b format, required fields;
+ -extCfgFile : Extend Profile, optional fields;
+ -signServer : remote signer plugin, required fields on remoteSign mode;
+ -signerPlugin : remote sign service url, required fields on remoteSign mode;
+ -onlineAuthMode : remote sign auth mode, required fields on remoteSign mode, including account;
+ -username : user account for online auth, required fields on remoteSign mode with account auth mode;
+ -userPwd : user password for online auth, required fields on remoteSign mode with account auth mode;
+
+ EXAMPLE:
+ sign-profile -mode localSign -keyAlias "oh-profile-key-v1" -outFile "/home/signed-profile.p7b"
+-keystoreFile "/home/profile-keypair.jks" -keystorePwd ****** -keyPwd ****** -signAlg SHA256withECDSA
+-profileCertFile "/home/provision-profile-release.cer" -inFile "/home/app1-profile-release.json"
+)";
+
+const std::string VERIFY_PROFILE_HELP_TXT = R"(
+ verify-profile[options]:
+ -inFile : signed Provision Profile file, p7b format, required fields;
+ -outFile : Verification result file(including verification result and profile content),
+ json format, optional; if not filled, it will be directly output to the console;
+ -extCfgFile : Extend Profile, optional fields;
+
+ EXAMPLE:
+ verify-profile -inFile "/home/signed-profile.p7b" -outFile "/home/VerifyResult.json"
+)";
+
+const std::string SIGN_APP_HELP_TXT = R"(
+ sign-app[options]:
+ -mode : signature mode, required fields, including localSign/remoteSign/remoteResign;
+ -keyAlias : key alias, required fields;
+ -keyPwd : key password, optional fields on localSign mode;
+ -appCertFile : application signature certificate file, required fields on localSign mode, optional fields
+ on remoteSign mode;
+ -profileFile : signed Provision Profile file, p7b format, required fields;
+ -profileSigned : indicates whether the profile file has a signature.The options are as follows
+ : 1 : yes; 0:no; default value:1. optional fields;
+ -inFile : input original application package file, .hap, .bin, and .elf format, required fields;
+ -signAlg : signature algorithm, required fields, including SHA256withECDSA/SHA384withECDSA;
+ -keystoreFile : keystore file, if signature mode is localSign, required fields on localSign mode,
+ JKS or P12 format;
+ -keystorePwd : keystore password, optional fields on localSign mode;
+ -outFile : output the signed Provision Profile file, required fields;
+ -extCfgFile : Extend Profile, optional fields;
+ -inForm : Enter the format of the original file.The supported file formats include.zip, .bin, and .elf.;
+ -compatibleVersion : min compatible api version for running app, required fields while input original
+ application package file format is hap;
+ -signServer : remote signer plugin, required fields on remoteSign mode;
+ -signerPlugin : remote sign service url, required fields on remoteSign mode;
+ -onlineAuthMode : remote sign auth mode, required fields on remoteSign mode, including account;
+ -username : user account for online auth, required fields on remoteSign mode with account auth mode;
+ -userPwd : user password for online auth, required fields on remoteSign mode with account auth mode;
+ -ext : extend parameters for remote signer plugin, optional fields;
+ -signCode : Whether the HAP file is signed code, The value 1 means enable sign code, and value 0 means
+ disable sign code.The default value is 1. It is optional.
+
+ EXAMPLE :
+ sign-app-mode localSign -keyAlias "oh-app1-key-v1" -appCertFile "/home/app-release-cert.cer" -signCode "1"
+-keystoreFile "/home/app-keypair.jks" -keystorePwd ****** -outFile "/home/app1-signed.hap -compatibleVersion 8"
+-profileFile "/home/signed-profile.p7b" -inFile "/home/app1-unsigned.hap" -signAlg SHA256withECDSA
+)";
+
+const std::string VERIFY_APP_HELP_TXT = R"(
+ verify-app[options]:
+ -inFile : signed application package file, hap or bin format, required fields;
+ -outCertChain : signed certificate chain file, required fields;
+ -outProfile : profile file in application package, required fields;
+ -extCfgFile : Extend Profile, optional fields;
+ -inForm : Enter the format of the original file.The supported file formats include.zip, .bin, and .elf.;
+
+ EXAMPLE:
+ verify-app-inFile "/home/app1-signed.hap" -outCertChain "outCertChain.cer" -outProfile "outprofile.p7b"
+)";
+
+const std::string HELP_END_TXT = R"(
+COMMANDS :
+ generate-keypair : generate key pair
+ generate-csr : generate certificate signing request
+ generate-cert : generate certificate in full, large and complete, any certificate can be generated
+ generate-ca : generate root / subject CA certificate, if the key does not exist, generate the key together
+ generate-app -cert : generate application debug / release certificate
+ generate-profile -cert : generate application debug / release certificate
+ sign-profile : Provision Profile file signature
+ verify-profile : Provision Profile file verification
+ sign-app : application package signature
+ verify-app : application package file verification
+)";
+/* help.txt all content */
+const std::string HELP_TXT = HELP_TXT_HEADER + KEYPAIR_HELP_TXT + CSR_HELP_TXT + CERT_HELP_TXT
++ CA_CERT_HELP_TXT + APP_CERT_HELP_TXT + PROFILE_CERT_HELP_TXT
++ SIGN_PROFILE_HELP_TXT + VERIFY_PROFILE_HELP_TXT + SIGN_APP_HELP_TXT
++ VERIFY_APP_HELP_TXT + HELP_END_TXT;
+}
+}
+#endif
\ No newline at end of file
diff --git a/hapsigntool_cpp/services/cmd/include/options.h b/hapsigntool_cpp/services/cmd/include/options.h
new file mode 100644
index 0000000000000000000000000000000000000000..059607ccc954fed9420a7ee85e837090ff6287ea
--- /dev/null
+++ b/hapsigntool_cpp/services/cmd/include/options.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNATRUETOOLS_OPTIONS_H
+#define SIGNATRUETOOLS_OPTIONS_H
+
+#include
+#include
+#include
+#include
+
+#include "signature_tools_log.h"
+
+namespace OHOS {
+namespace SignatureTools {
+class Options : public std::unordered_map> {
+public:
+ Options() = default;
+ ~Options() = default;
+ char* GetChars(const std::string key);
+ std::string GetString(const std::string key);
+ std::string GetString(const std::string key, std::string checkStr);
+ int GetInt(const std::string key);
+ bool Equals(const std::string key1, const std::string& key2);
+ bool Required(std::initializer_list keys);
+ bool IsEmpty(std::string cs);
+ bool GetBool(const std::string key);
+public:
+ /* Key alias parameter name. */
+ static const std::string KEY_ALIAS;
+
+ /* Key right parameter name. */
+ static const std::string KEY_RIGHTS;
+
+ /* Key size parameter name(NIST-P-256, NIST-P-384). */
+ static const std::string KEY_SIZE;
+
+ /* Key alg parameter name(ECC). */
+ static const std::string KEY_ALG;
+
+ /* Keystore file parameter name. */
+ static const std::string KEY_STORE_FILE;
+
+ /* Keystore right parameter name. */
+ static const std::string KEY_STORE_RIGHTS;
+
+ /* Issuer key alias parameter name. */
+ static const std::string ISSUER_KEY_ALIAS;
+
+ /* Issuer key right parameter name. */
+ static const std::string ISSUER_KEY_RIGHTS;
+
+ /* Issuer Key Store File parameter name. */
+ static const std::string ISSUER_KEY_STORE_FILE;
+
+ /* Issuer Key Store Pwd parameter name. */
+ static const std::string ISSUER_KEY_STORE_RIGHTS;
+
+ /* issuer subject. */
+ static const std::string ISSUER;
+
+ /* issuer subject. */
+ static const std::string INFORM;
+
+ /* certificate subject. */
+ static const std::string SUBJECT;
+
+ /* the validity period of the certificate. */
+ static const std::string VALIDITY;
+
+ /* signature algorithm. */
+ static const std::string SIGN_ALG;
+
+ /* length of path. */
+ static const std::string BASIC_CONSTRAINTS_PATH_LEN;
+
+ /* outfile. */
+ static const std::string OUT_FILE;
+
+ /* End file type of cert. values in: cert / certChain */
+ static const std::string OUT_FORM;
+
+ /* Sub cert for sig. */
+ static const std::string SUB_CA_CERT_FILE;
+
+ /* Ca cert file parameter name. */
+ static const std::string CA_CERT_FILE;
+
+ /* In file parameter name. */
+ static const std::string IN_FILE;
+ static const std::string PROFILE_CERT_FILE;
+ static const std::string APP_CERT_FILE;
+ static const std::string KEY_USAGE;
+ static const std::string EXT_KEY_USAGE;
+ static const std::string KEY_USAGE_CRITICAL;
+ static const std::string EXT_KEY_USAGE_CRITICAL;
+ static const std::string BASIC_CONSTRAINTS;
+ static const std::string BASIC_CONSTRAINTS_CRITICAL;
+ static const std::string BASIC_CONSTRAINTS_CA;
+
+ /* Out form includes all forms. */
+ static const std::string OUT_FORM_SCOPE;
+ static const std::string MODE;
+ static const std::string OUT_CERT_CHAIN;
+ static const std::string OUT_PROFILE;
+ static const std::string PROOF_FILE;
+ static const std::string PROFILE_FILE;
+ static const std::string PROFILE_SIGNED;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_OPTIONS_H
diff --git a/hapsigntool_cpp/services/cmd/include/params.h b/hapsigntool_cpp/services/cmd/include/params.h
new file mode 100644
index 0000000000000000000000000000000000000000..775b43c77a3d6250e93d2ed2f769aca25a7aa6ab
--- /dev/null
+++ b/hapsigntool_cpp/services/cmd/include/params.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNATRUETOOLS_PARAMS_H
+#define SIGNATRUETOOLS_PARAMS_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "options.h"
+#include "signature_algorithm_helper.h"
+#include "param_constants.h"
+
+namespace OHOS {
+namespace SignatureTools {
+class Params {
+public:
+ virtual ~Params() = default;
+ Params() = default;
+ virtual std::string GetMethod();
+ virtual void SetMethod(const std::string& method);
+ virtual Options* GetOptions();
+ static std::unordered_set InitParamField(const std::vector& paramFields);
+ static bool GetSignatureAlgorithm(const std::string& signatureAlgorithm, SignatureAlgorithmHelper& out);
+
+public:
+ static const std::string GENERATE_APP_CERT;
+ static const std::string GENERATE_CA;
+ static const std::string GENERATE_CERT;
+ static const std::string GENERATE_CSR;
+ static const std::string GENERATE_KEYPAIR;
+ static const std::string GENERATE_PROFILE_CERT;
+ static const std::string SIGN_APP;
+ static const std::string SIGN_PROFILE;
+ static const std::string VERIFY_APP;
+ static const std::string VERIFY_PROFILE;
+
+private:
+ std::string method;
+ std::shared_ptr options = std::make_shared();
+};
+using ParamsSharedPtr = std::shared_ptr;
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_PARAMS_H
diff --git a/hapsigntool_cpp/services/cmd/include/params_run_tool.h b/hapsigntool_cpp/services/cmd/include/params_run_tool.h
new file mode 100644
index 0000000000000000000000000000000000000000..5b0e8da461dfa3f597bc88c7073bdcc3eb6b010f
--- /dev/null
+++ b/hapsigntool_cpp/services/cmd/include/params_run_tool.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024-2024 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SIGNATRUETOOLS_HAP_SIGN_TOOL_H
+#define SIGNATRUETOOLS_HAP_SIGN_TOOL_H
+
+#include