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/BUILD.gn b/hapsigntool_cpp/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..b8be05beec614bd5c8debc4ec15ba4a5bcb69d3a
--- /dev/null
+++ b/hapsigntool_cpp/BUILD.gn
@@ -0,0 +1,114 @@
+# 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("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("signature_tools.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",
+ ]
+ 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_api}/include",
+ "${signature_tools_signer}/include",
+ "//third_party/openssl/include",
+ "//third_party/openssl/crypto/pkcs12",
+]
+
+signature_tools_main_src = [
+ "main.cpp",
+ "${signature_tools_api}/src/localization_adapter.cpp",
+ "${signature_tools_api}/src/sign_tool_service_impl.cpp",
+ "${signature_tools_api}/src/cert_tools.cpp",
+ "${signature_tools_signer}/src/signer_factory.cpp",
+ "${signature_tools_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 = [ "SIGNATURE_LOG_DEBUG" ]
+
+ 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",
+ "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/api/include/cert_tools.h b/hapsigntool_cpp/api/include/cert_tools.h
new file mode 100644
index 0000000000000000000000000000000000000000..f95a6add846816673d51cad8bb3890ec18a2cefc
--- /dev/null
+++ b/hapsigntool_cpp/api/include/cert_tools.h
@@ -0,0 +1,71 @@
+/*
+ * 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:
+ 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 SetBisicConstraints(Options* options, X509* cert);
+ static bool SetBisicConstraintsPathLen(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* caPrikey, 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(uint8_t* serialNum, int length);
+ static bool SetCertVersion(X509* cert, int versionNum);
+ static bool SetCertSerialNum(X509* cert);
+ 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 SetAuthorizeKeyIdentifierExt(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);
+ CertTools() = default;
+ ~CertTools() = default;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_CERT_TOOLS_H
diff --git a/hapsigntool_cpp/api/include/localization_adapter.h b/hapsigntool_cpp/api/include/localization_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..3a969685673ea20d9d72db5d26265d31294e18ae
--- /dev/null
+++ b/hapsigntool_cpp/api/include/localization_adapter.h
@@ -0,0 +1,78 @@
+/*
+ * 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);
+ int GetKeyPair(bool autoCreate, EVP_PKEY** keyPair);
+ int IssuerKeyStoreFile(EVP_PKEY** keyPair, bool autoCreate);
+ int KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate);
+
+ void ResetPwd();
+ void SetIssuerKeyStoreFile(bool issuerKeyStoreFile);
+ void AppAndProfileAssetsRealse(std::initializer_list keys,
+ std::initializer_list reqs,
+ std::initializer_list certs);
+
+ bool IsOutFormChain();
+ bool IsRemoteSigner();
+
+ const std::string GetSignAlg() const;
+ const std::string GetOutFile();
+ const std::string GetInFile();
+
+ Options* GetOptions();
+ EVP_PKEY* GetAliasKey(bool autoCreate);
+ EVP_PKEY* GetIssureKeyByAlias();
+ X509* GetSubCaCertFile();
+ X509* GetCaCertFile();
+ STACK_OF(X509*) GetSignCertChain();
+ std::vector GetCertsFromFile(std::string& certPath, const std::string& logTitle);
+
+private:
+ void ResetChars(char* chars);
+
+public:
+ Options* options;
+ std::unique_ptr keyStoreHelper;
+
+private:
+ static constexpr int MIN_CERT_CHAIN_SIZE = 2;
+ static constexpr int MAX_CERT_CHAIN_SIZE = 3;
+ bool isIssuerKeyStoreFile;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_LOCALIIZATION_ADAPTER_H
diff --git a/hapsigntool_cpp/api/include/service_api.h b/hapsigntool_cpp/api/include/service_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..968df287baec4243debdd77685da4c4383d2a455
--- /dev/null
+++ b/hapsigntool_cpp/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/api/include/sign_tool_service_impl.h b/hapsigntool_cpp/api/include/sign_tool_service_impl.h
new file mode 100644
index 0000000000000000000000000000000000000000..878e566054668fb3cf72fa57dc23fa6684030c9f
--- /dev/null
+++ b/hapsigntool_cpp/api/include/sign_tool_service_impl.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_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:
+ static int GetProvisionContent(const std::string& input, std::string& ret);
+
+ 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* cert, const std::string& outPutPath);
+ 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/api/src/cert_tools.cpp b/hapsigntool_cpp/api/src/cert_tools.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..37826e945bafe816fc7caa4002d59ed89b9b3e2d
--- /dev/null
+++ b/hapsigntool_cpp/api/src/cert_tools.cpp
@@ -0,0 +1,828 @@
+/*
+ * 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"
+#include "cmd_util.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");
+ return false;
+ }
+
+ if (PEM_write_bio_X509(certBio, cert) < 0) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("PEM_write_bio_X509 failed");
+ BIO_free(certBio);
+ return false;
+ }
+ BIO_free(certBio);
+ return true;
+}
+
+bool CertTools::SetBisicConstraints(Options* options, X509* cert)
+{
+ bool basicCon = options->GetBool(Options::BASIC_CONSTRAINTS);
+ if (basicCon) {
+ bool basicConstraintsCritical = options->GetBool(Options::BASIC_CONSTRAINTS_CRITICAL);
+ int critial = basicConstraintsCritical ? 1 : 0;
+ bool basicConstraintsCa = options->GetBool(Options::BASIC_CONSTRAINTS_CA);
+ std::string ContainCa = basicConstraintsCa ? "CA:TRUE" : "CA:FALSE";
+ std::string constraints = ContainCa + "," + "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, constraints.c_str());
+ if (!X509_EXTENSION_set_critical(ext, critial)) {
+ SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage ");
+ X509_EXTENSION_free(ext);
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("X509_add_ext failed");
+ X509_EXTENSION_free(ext);
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ X509_EXTENSION_free(ext);
+ }
+
+ return true;
+}
+
+bool CertTools::SetBisicConstraintsPathLen(Options* options, X509* cert)
+{
+ 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 (!X509_EXTENSION_set_critical(ext, 1)) {
+ SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage ");
+ X509_EXTENSION_free(ext);
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("X509_add_ext failed\n");
+ X509_EXTENSION_free(ext);
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+ }
+ X509_EXTENSION_free(ext);
+ return true;
+}
+
+bool CertTools::SignForSubCert(X509* cert, X509_REQ* subcsr, X509_REQ* rootcsr, EVP_PKEY* caPrikey, Options* options)
+{
+ bool result = false;
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ EVP_PKEY* pubKey = X509_REQ_get_pubkey(subcsr);
+ X509_NAME* issuerName = X509_REQ_get_subject_name(rootcsr);
+ X509_NAME* subjectName = X509_REQ_get_subject_name(subcsr);
+ if (pubKey == NULL) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_get_pubkey failed");
+ goto err;
+ }
+ if (caPrikey == nullptr || rootcsr == nullptr || subcsr == nullptr) {
+ SIGNATURE_TOOLS_LOGE("Sign failed because of caPrikey, roocsr or subcsr is nullptr");
+ goto err;
+ }
+ result = (!X509_set_pubkey(cert, pubKey));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_pubkey failed");
+ goto err;
+ }
+ result = (!X509_set_issuer_name(cert, issuerName));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
+ goto err;
+ }
+ result = (!X509_set_subject_name(cert, subjectName));
+ if (result) {
+ SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed");
+ goto err;
+ }
+ result = (!SignCert(cert, caPrikey, signAlg));
+ if (result) {
+ goto err;
+ }
+ EVP_PKEY_free(pubKey);
+ return true;
+err:
+ EVP_PKEY_free(pubKey);
+ X509_NAME_free(issuerName);
+ X509_NAME_free(subjectName);
+ 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();
+ int validity = options->GetInt(Options::VALIDITY);
+ result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert));
+ if (result) {
+ goto err;
+ }
+ result = SetCertValidity(cert, validity);
+ if (!result) {
+ goto err;
+ }
+ result = (!SetBisicConstraintsPathLen(options, cert) ||
+ !SetKeyIdentifierExt(cert) ||
+ !SetAuthorizeKeyIdentifierExt(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");
+ goto err;
+ }
+
+ if (X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
+ goto err;
+ }
+
+ if (X509_set_issuer_name(cert, X509_REQ_get_subject_name(certReq)) != 1) {
+ SIGNATURE_TOOLS_LOGE("X509_set_issuer_name failed");
+ goto err;
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+X509* CertTools::GenerateRootCertificate(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
+{
+ bool result = false;
+ X509* cert = X509_new();
+ int validity = options->GetInt(Options::VALIDITY);
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert));
+ if (result) {
+ goto err;
+ }
+ if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
+ goto err;
+ }
+ result = (!SetBisicConstraintsPathLen(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");
+ 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");
+ goto err;
+ }
+ subCert = SignCsrGenerateCert(rootcsr, subcsr, keyPair, options);
+ if (subCert == nullptr) {
+ SIGNATURE_TOOLS_LOGE("failed to generate the subCert");
+ 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 = 0;
+ if (keyUsage.empty()) {
+ key = X509v3_KU_KEY_CERT_SIGN | X509v3_KU_CRL_SIGN;
+ if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) {
+ 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 {
+ bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL);
+ int crit = keyUsageCritical > 0 ? 1 : 0;
+ std::vector vecs = StringUtils::SplitString(keyUsage.c_str(), ',');
+ for (auto &vec : vecs) {
+ key |= externDic[vec];
+ }
+ if (keyUsageInt == NULL || !ASN1_INTEGER_set(keyUsageInt, key)) {
+ SIGNATURE_TOOLS_LOGE("failed to set asn1_integer");
+ ASN1_INTEGER_free(keyUsageInt);
+ return false;
+ }
+ if (!X509_add1_ext_i2d(cert, NID_key_usage, keyUsageInt, crit, 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;
+ bool keyUsageCritical = options->GetBool(Options::KEY_USAGE_CRITICAL);
+ int crit = keyUsageCritical ? 1 : 0;
+ 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 (!X509_EXTENSION_set_critical(ext, crit)) {
+ SIGNATURE_TOOLS_LOGE("failed to set critical for extKeyUsage ");
+ 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 ");
+ 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");
+ goto err;
+ }
+
+ if (!X509_set_subject_name(cert, X509_REQ_get_subject_name(certReq))) {
+ SIGNATURE_TOOLS_LOGE("X509_set_subject_name failed");
+ goto err;
+ }
+ if ((options->GetString(Options::SIGN_ALG)) == SIGN_ALG_SHA256) {
+ if (!X509_sign(cert, keyPair, EVP_sha256())) {
+ SIGNATURE_TOOLS_LOGE("X509_sign failed");
+ goto err;
+ }
+ } else {
+ if (!X509_sign(cert, keyPair, EVP_sha384())) {
+ SIGNATURE_TOOLS_LOGE("X509_sign failed");
+ goto err;
+ }
+ }
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ return false;
+}
+
+X509* CertTools::GenerateCert(EVP_PKEY* keyPair, X509_REQ* certReq, Options* options)
+{
+ 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");
+ return nullptr;
+ }
+
+ X509* cert = X509_new();
+ result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) ||
+ !SetCertSerialNum(cert) ||
+ !SetKeyIdentifierExt(cert));
+ if (result) {
+ goto err;
+ }
+ validity = options->GetInt(Options::VALIDITY);
+ if (!SetCertValidityStartAndEnd(cert, DEFAULT_START_VALIDITY, validity)) {
+ goto err;
+ }
+
+ result = (!SetBisicConstraints(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");
+ goto err;
+ }
+
+ name = BuildDN(subject, req);
+ if (!name) {
+ SIGNATURE_TOOLS_LOGE("failed to add subject into cert");
+ goto err;
+ }
+
+ if (signAlgorithm == SIGN_ALG_SHA256) {
+ if (!X509_REQ_sign(req, evpPkey, EVP_sha256())) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed");
+ goto err;
+ }
+ } else if (signAlgorithm == SIGN_ALG_SHA384) {
+ if (!X509_REQ_sign(req, evpPkey, EVP_sha384())) {
+ SIGNATURE_TOOLS_LOGE("X509_REQ_sign failed");
+ 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");
+ 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");
+ 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");
+ 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");
+ return false;
+ }
+ return true;
+}
+
+bool CertTools::SetCertSerialNum(X509* cert)
+{
+ BN_CTX* ctx = BN_CTX_new();
+ BIGNUM* bignum = BN_new();
+ uint8_t serialNumberValue[RANDOM_SERIAL_NUMBER_LENGTH] = {0};
+ if (!SerialNumberBuilder(serialNumberValue, sizeof(serialNumberValue))) {
+ goto err;
+ }
+ if (!BN_bin2bn(serialNumberValue, sizeof(serialNumberValue), bignum)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ goto err;
+ }
+ if (BN_is_negative(bignum)) {
+ BN_set_negative(bignum, 0); // Replace negative numbers with positive ones
+ }
+ if (!BN_to_ASN1_INTEGER(bignum, X509_get_serialNumber(cert))) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ goto err;
+ }
+ BN_CTX_free(ctx);
+ BN_free(bignum);
+ return true;
+err:
+ SIGNATURE_TOOLS_LOGE("set x509 cert serial number failed");
+ BN_CTX_free(ctx);
+ BN_free(bignum);
+ return false;
+}
+
+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");
+ 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");
+ return false;
+ }
+ if (!X509_set_subject_name(cert, subject)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set X509 cert subject name failed");
+ 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");
+ return false;
+ }
+ if (!X509_gmtime_adj(X509_getm_notAfter(cert), vilidityEnd)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set cert vilidity end time failed");
+ 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");
+ return false;
+ }
+ if (!X509_set_pubkey(cert, publicKey)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ EVP_PKEY_free(publicKey);
+ SIGNATURE_TOOLS_LOGE("set public key to cert failed");
+ 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");
+ 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");
+ 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");
+ 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");
+ 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");
+ 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");
+ ASN1_OCTET_STRING_free(pubKeyDigestData);
+ X509_EXTENSION_free(subKeyIdentifierExtension);
+ return false;
+ }
+ ASN1_OCTET_STRING_free(pubKeyDigestData);
+ X509_EXTENSION_free(subKeyIdentifierExtension);
+ return true;
+}
+
+bool CertTools::SetAuthorizeKeyIdentifierExt(X509* cert)
+{
+ unsigned char key_id[] = { 0x73, 0x3a, 0x81, 0x87, 0x8f, 0x95, 0xc1, 0x94,
+ 0xcf, 0xef, 0xab, 0x6f, 0x7f, 0x01, 0x52, 0x86,
+ 0xa3, 0xc2, 0x01, 0xc2 };
+ unsigned int key_id_len = sizeof(key_id);
+ X509_EXTENSION* ext = nullptr;
+ AUTHORITY_KEYID* akid = AUTHORITY_KEYID_new();
+ akid->keyid = ASN1_OCTET_STRING_new();
+ if (!ASN1_OCTET_STRING_set(akid->keyid, key_id, key_id_len)) {
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ SIGNATURE_TOOLS_LOGE("set ANS1 pubKeyDigestData failed");
+ AUTHORITY_KEYID_free(akid);
+ return false;
+ }
+ ext = X509V3_EXT_i2d(NID_authority_key_identifier, 1, akid);
+ if (!X509_add_ext(cert, ext, -1)) {
+ SIGNATURE_TOOLS_LOGE("Failed to add AKI extension to certificate");
+ X509_EXTENSION_free(ext);
+ AUTHORITY_KEYID_free(akid);
+ return false;
+ }
+
+ X509_EXTENSION_free(ext);
+ AUTHORITY_KEYID_free(akid);
+ 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");
+ ASN1_OCTET_STRING_free(certSignCapacityData);
+ return false;
+ }
+ // generate user-define Nid
+ ASN1_OBJECT* nid = OBJ_txt2obj(X509_EXT_OID.c_str(), 1);
+ 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");
+ 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");
+ 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(uint8_t* serialNum, int length)
+{
+ if (RAND_bytes(serialNum, length) != 1) { // this function is thread safity
+ SIGNATURE_TOOLS_LOGE("serial number build failed");
+ 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
+ X509_REQ* issuerReq = nullptr;
+ bool result = false;
+ issuerReq = X509_REQ_new();
+ std::string issuerStr = adapter.options->GetString(adapter.options->ISSUER);
+ int validity = adapter.options->GetInt(adapter.options->VALIDITY);
+ std::string signAlg = adapter.options->GetString(adapter.options->SIGN_ALG);
+
+ result = (!SetCertVersion(cert, DEFAULT_CERT_VERSION) || !SetCertSerialNum(cert));
+ if (result) {
+ goto err;
+ }
+ result = (!SetCertIssuerName(cert, BuildDN(issuerStr, issuerReq)) || !SetCertSubjectName(cert, csr));
+ if (result) {
+ goto err;
+ }
+ result = (!SetCertValidity(cert, validity) || !SetCertPublickKey(cert, csr));
+ if (result) {
+ goto err;
+ }
+ result = (!SetBasicExt(cert) || !SetkeyUsageExt(cert) || !SetKeyUsageEndExt(cert));
+ if (result) {
+ goto err;
+ }
+ result = (!SetKeyIdentifierExt(cert) || !SetSignCapacityExt(cert, signCapacity, capacityLen));
+ if (result) {
+ goto err;
+ }
+ if (!SignCert(cert, issuerKeyPair, signAlg)) {
+ goto err;
+ }
+
+ adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {});
+ return cert; // return x509 assets
+err:
+ adapter.AppAndProfileAssetsRealse({}, {issuerReq}, {cert});
+ return nullptr;
+}
+
+} // namespace SignatureTools
+} // namespace OHOS
+
diff --git a/hapsigntool_cpp/api/src/localization_adapter.cpp b/hapsigntool_cpp/api/src/localization_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..64f5fdeb53c8fd1ccab2d9be06187e4574331652
--- /dev/null
+++ b/hapsigntool_cpp/api/src/localization_adapter.cpp
@@ -0,0 +1,319 @@
+/*
+ * 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"
+#include "constant.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 = options->GetString(Options::KEY_STORE_FILE);
+ if (!keyStoreHelper->IsKeyStoreFileExist(keyStoreFile)) {
+ return RET_FAILED;
+ }
+
+ EVP_PKEY* keyPair = nullptr;
+ char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
+ keyStoreHelper->SetIsRegen(true);
+ int status = keyStoreHelper->ReadKeyStore(keyStoreFile, keyStorePwd, alias, keyPwd, &keyPair);
+ EVP_PKEY_free(keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ }
+
+ return RET_FAILED;
+}
+
+void LocalizationAdapter::ResetPwd()
+{
+ char* keyRights = options->GetChars(Options::KEY_RIGHTS);
+ if (keyRights != nullptr) {
+ ResetChars(keyRights);
+ }
+ char* keyStoreRights = options->GetChars(Options::KEY_STORE_RIGHTS);
+ if (keyStoreRights != nullptr) {
+ ResetChars(keyStoreRights);
+ }
+ char* issuerKeyRights = options->GetChars(Options::ISSUER_KEY_RIGHTS);
+ if (issuerKeyRights != nullptr) {
+ ResetChars(issuerKeyRights);
+ }
+ char* issuerKeyStoreRights = 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 (keyStoreHelper == nullptr) {
+ keyStoreHelper = std::make_unique();
+ }
+
+ int status = GetKeyPair(autoCreate, &keyPair);
+ if (status == RET_FAILED) {
+ EVP_PKEY_free(keyPair);
+ return nullptr;
+ }
+
+ return keyPair;
+}
+
+int LocalizationAdapter::GetKeyPair(bool autoCreate, EVP_PKEY** keyPair)
+{
+ keyStoreHelper->SetPassWordStatus(true);
+ keyStoreHelper->SetIsRegen(autoCreate);
+
+ int status = RET_FAILED;
+ if (isIssuerKeyStoreFile) {
+ status = IssuerKeyStoreFile(keyPair, autoCreate);
+ } else {
+ status = KeyStoreFile(keyPair, autoCreate);
+ }
+ isIssuerKeyStoreFile = false;
+ return status;
+}
+
+int LocalizationAdapter::KeyStoreFile(EVP_PKEY** keyPair, bool autoCreate)
+{
+ std::string keyStorePath = "";
+ keyStorePath = options->GetString(Options::KEY_STORE_FILE);
+ char* keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
+ char* keyPwd = options->GetChars(Options::KEY_RIGHTS);
+ std::string keyAlias = options->GetString(Options::KEY_ALIAS);
+ bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStorePath);
+ if (fileStatus) {
+ int status = keyStoreHelper->ReadKeyStore(keyStorePath, keyStorePwd, keyAlias, keyPwd, keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ }
+
+ if (!keyStoreHelper->GetPassWordStatus()) {
+ autoCreate = false;
+ }
+ }
+ if (autoCreate) {
+ std::string keyAlg = options->GetString(Options::KEY_ALG);
+ int keySize = options->GetInt(Options::KEY_SIZE);
+ *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
+ int status = keyStoreHelper->WriteKeyStore(*keyPair, keyStorePath, keyStorePwd, 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 = options->GetString(Options::ISSUER_KEY_STORE_FILE);
+ char* keyStorePwd = options->GetChars(Options::ISSUER_KEY_STORE_RIGHTS);
+ std::string keyAlias = options->GetString(Options::ISSUER_KEY_ALIAS);
+ char* keyPwd = options->GetChars(Options::ISSUER_KEY_RIGHTS);
+
+ if (keyStore.empty()) {
+ keyStore = options->GetString(Options::KEY_STORE_FILE);
+ keyStorePwd = options->GetChars(Options::KEY_STORE_RIGHTS);
+ }
+
+ bool fileStatus = keyStoreHelper->IsKeyStoreFileExist(keyStore);
+ if (fileStatus) {
+ int status = keyStoreHelper->ReadKeyStore(keyStore, keyStorePwd, keyAlias, keyPwd, keyPair);
+ if (status == RET_OK) {
+ return RET_OK;
+ }
+
+ if (!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 = options->GetString(Options::KEY_ALG);
+ int keySize = options->GetInt(Options::KEY_SIZE);
+ *keyPair = keyStoreHelper->GenerateKeyPair(keyAlg, keySize);
+ if (keyStore.empty()) {
+ return keyStoreHelper->WriteKeyStore(*keyPair, keyStore, keyStorePwd, keyAlias, keyPwd);
+ }
+ }
+
+ return RET_FAILED;
+}
+
+void LocalizationAdapter::SetIssuerKeyStoreFile(bool issuerKeyStoreFile)
+{
+ this->isIssuerKeyStoreFile = issuerKeyStoreFile;
+}
+
+STACK_OF(X509)* LocalizationAdapter::GetSignCertChain()
+{
+ STACK_OF(X509)* certificates = NULL;
+ std::string certPath = options->GetString(Options::PROFILE_CERT_FILE);
+ if (certPath.empty()) {
+ certPath = options->GetString(Options::APP_CERT_FILE);
+ }
+ certificates = sk_X509_new(NULL);
+ if (certificates == NULL) {
+ SIGNATURE_TOOLS_LOGE("sk_X509_new failed");
+ return NULL;
+ }
+ std::vector certs = GetCertsFromFile(certPath, Options::PROFILE_CERT_FILE);
+ 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());
+ goto err;
+ }
+ return certificates;
+err:
+ sk_X509_pop_free(certificates, X509_free);
+ return NULL;
+}
+
+EVP_PKEY* LocalizationAdapter::GetIssureKeyByAlias()
+{
+ return GetAliasKey(false);
+}
+
+bool LocalizationAdapter::IsOutFormChain()
+{
+ std::string checkStr = OUT_FORM_CERT_CHAIN;
+ std::string outForm = options->GetString(Options::OUT_FORM, checkStr);
+ if (outForm.compare(OUT_FORM_CERT_CHAIN) == 0) {
+ return true;
+ }
+ return false;
+}
+
+X509* LocalizationAdapter::GetSubCaCertFile()
+{
+ std::string certPath = 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 = options->GetString(Options::CA_CERT_FILE);
+ return GetCertsFromFile(certPath, Options::CA_CERT_FILE).at(0);
+}
+
+const std::string LocalizationAdapter::GetOutFile()
+{
+ return options->GetString(Options::OUT_FILE);
+}
+
+std::vector LocalizationAdapter::GetCertsFromFile(std::string& certPath, const std::string& logTitle)
+{
+ SIGNATURE_TOOLS_LOGD("outPutPath = %s , logTitle = %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 options->GetString(Options::IN_FILE);
+}
+
+bool LocalizationAdapter::IsRemoteSigner()
+{
+ std::string mode = options->GetString(Options::MODE, LOCAL_SIGN);
+ return StringUtils::CaseCompare(mode, REMOTE_SIGN);
+}
+
+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/api/src/sign_tool_service_impl.cpp b/hapsigntool_cpp/api/src/sign_tool_service_impl.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4067ea69c60b1ec07e57144dd106dd703dd6d2a7
--- /dev/null
+++ b/hapsigntool_cpp/api/src/sign_tool_service_impl.cpp
@@ -0,0 +1,699 @@
+/*
+ * 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!");
+ 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!");
+ 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!");
+ 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.");
+ EVP_PKEY_free(keyPair);
+ return false;
+ }
+ if (subject.empty()) {
+ PrintErrorNumberMsg("INVALIDPARAM_ERROR",
+ INVALIDPARAM_ERROR,
+ "Please check if subject has been specified which is required.");
+ EVP_PKEY_free(keyPair);
+ 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);
+
+ if (!(keyPair = adapter->GetAliasKey(false))) { // get keypair
+ goto err;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ if (!(issueKeyPair = adapter->GetIssureKeyByAlias())) { // get issuer keypair
+ goto err;
+ }
+ adapter->ResetPwd(); // clean pwd for safety
+ csr = GetCsr(keyPair, signAlg, subject);
+ if (!csr) { // get CSR request
+ goto err;
+ }
+ x509Certificate = CertTools::GenerateEndCert(csr, issueKeyPair, *adapter,
+ APP_SIGNING_CAPABILITY,
+ sizeof(APP_SIGNING_CAPABILITY)); // get app x509 cert
+ if (!x509Certificate) {
+ PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, "generate app cert failed");
+ goto err;
+ }
+ if (!X509CertVerify(x509Certificate, issueKeyPair)) {
+ goto err;
+ }
+ if (!GetAndOutPutCert(*adapter, x509Certificate)) {
+ goto err;
+ }
+
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {x509Certificate}); // realse heap memory
+ return true;
+
+err:
+ 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);
+
+ if (!(keyPair = adapter->GetAliasKey(false))) { // get keypair
+ goto err;
+ }
+ adapter->SetIssuerKeyStoreFile(true);
+ if (!(issueKeyPair = adapter->GetIssureKeyByAlias())) { // get issuer keypair
+ goto err;
+ }
+ adapter->ResetPwd(); // clean pwd for safety
+ csr = GetCsr(keyPair, signAlg, subject);
+ if (!csr) { // get CSR request
+ goto err;
+ }
+ x509Certificate = CertTools::GenerateEndCert(csr, issueKeyPair, *adapter,
+ PROFILE_SIGNING_CAPABILITY,
+ sizeof(PROFILE_SIGNING_CAPABILITY)); // get profile x509 cert
+ if (!x509Certificate) {
+ PrintErrorNumberMsg("CERTIFICATE_ERROR", CERTIFICATE_ERROR, "generate profile cert failed");
+ goto err;
+ }
+ if (!X509CertVerify(x509Certificate, issueKeyPair)) {
+ goto err;
+ }
+ if (!GetAndOutPutCert(*adapter, x509Certificate)) { // output cert to file
+ goto err;
+ }
+
+ adapter->AppAndProfileAssetsRealse({issueKeyPair, keyPair}, {csr}, {x509Certificate}); // realse heap memory
+ return true;
+
+err:
+ 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 entity cert
+ successflag = (!(subCaCert = adapter.GetSubCaCertFile()) ||
+ !(rootCaCert = adapter.GetCaCertFile()));
+ if (successflag) {
+ return false;
+ }
+ certificates.emplace_back(subCaCert); // add sub ca cert
+ certificates.emplace_back(rootCaCert); // add root ca cert
+
+ if (outFile.empty()) {
+ successflag = PrintX509CertChainFromMemory(certificates); // print certchain to cmd
+ adapter.AppAndProfileAssetsRealse({}, {}, {certificates[1], certificates[2]});
+ return successflag;
+ }
+ successflag = OutPutCertChain(certificates, adapter.GetOutFile()); // out put certchain to file
+ adapter.AppAndProfileAssetsRealse({}, {}, {certificates[1], certificates[2]});
+ return successflag;
+ }
+
+ if (outFile.empty()) {
+ successflag = PrintX509CertFromMemory(cert); // print cert to cmd
+ return successflag;
+ }
+ successflag = OutPutCert(cert, adapter.GetOutFile()); // out put cert to file
+ return successflag;
+}
+
+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");
+ return false;
+ }
+ if (ProfileSignTool::GenerateP7b(adapter, provisionContent, p7b) < 0) {
+ SIGNATURE_TOOLS_LOGE("generate P7b data failed");
+ return false;
+ }
+ if (FileUtils::Write(p7b, outFile) < 0) {
+ SIGNATURE_TOOLS_LOGE("write p7b data failed");
+ return false;
+ }
+ return true;
+}
+
+bool SignToolServiceImpl::SignHap(Options* options)
+{
+ std::string mode = options->GetString(Options::MODE);
+ std::shared_ptr signProvider;
+ if (LOCAL_SIGN == mode) {
+ signProvider = std::make_shared();
+ } else if (REMOTE_SIGN == 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");
+ return false;
+ }
+ PKCS7Data p7Data;
+ if (p7Data.Parse(p7b) < 0) {
+ SIGNATURE_TOOLS_LOGE("verify profile failed");
+ return false;
+ }
+ if (p7Data.Verify() < 0) {
+ SIGNATURE_TOOLS_LOGE("verify profile failed");
+ return false;
+ }
+ const std::string outFile = adapter.GetOutFile();
+ std::string originalData;
+ if (p7Data.GetContent(originalData) < 0) {
+ SIGNATURE_TOOLS_LOGE("get content failed");
+ 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 = %s", outPutPath.c_str());
+ BIO* bio = nullptr;
+ if (!(bio = BIO_new_file(outPutPath.c_str(), "wb"))) {
+ SIGNATURE_TOOLS_LOGE("failed to open file %s", outPutPath.c_str());
+ 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);
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ BIO_free(bio);
+ return false;
+}
+
+bool SignToolServiceImpl::OutPutCert(X509* cert, const std::string& outPutPath)
+{
+ BIO* bio = BIO_new_file(outPutPath.c_str(), "wb");
+ if (!bio) {
+ SIGNATURE_TOOLS_LOGE("failed to open file: %s", outPutPath.c_str());
+ goto err;
+ }
+ if (!PEM_write_bio_X509(bio, cert)) {
+ SIGNATURE_TOOLS_LOGE("failed to write cert to file!");
+ goto err;
+ }
+ BIO_free(bio);
+ return true;
+err:
+ VerifyHapOpensslUtils::GetOpensslErrorMessage();
+ 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!");
+ 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");
+ 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 chain 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/bundle.json b/hapsigntool_cpp/bundle.json
new file mode 100644
index 0000000000000000000000000000000000000000..decf68af895587a4a21559bb48f55ac9368a1ac9
--- /dev/null
+++ b/hapsigntool_cpp/bundle.json
@@ -0,0 +1,53 @@
+{
+ "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",
+ "json"
+ ],
+ "third_party": [
+ "bzip2",
+ "openssl",
+ "jsoncpp",
+ "zlib"
+ ]
+ },
+ "build": {
+ "sub_component": [
+ "//developtools/hapsigner/hapsigntool_cpp:hap-sign-tool"
+ ],
+ "inner_kits": [],
+ "test": [
+ ]
+ }
+ }
+}
diff --git a/hapsigntool_cpp/cmd/include/cmd_util.h b/hapsigntool_cpp/cmd/include/cmd_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..8bf2238905ced1426f88c20844ccd37a419a4cc7
--- /dev/null
+++ b/hapsigntool_cpp/cmd/include/cmd_util.h
@@ -0,0 +1,54 @@
+/*
+ * 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:
+ static bool Convert2Params(char** args, size_t size, const ParamsSharedPtr& param);
+ static bool JudgeAlgType(const std::string& keyAlg);
+ static bool JudgeSize(const int size);
+ static bool JudgeSignAlgType(const std::string& signAlg);
+ static bool VerifyType(const std::string& inputType);
+ static bool VerifyTypes(const std::string& inputType);
+ static bool VerifyType(const std::string& inputtype, const std::string& supportTypes);
+ static bool String2Bool(Options* options, const std::string& option);
+ static constexpr int ARGS_MIN_LEN = 2;
+
+private:
+ static int GetCommandParameterKey(const char strChar, std::string& strChars,
+ std::vector& trustList, std::string& keyStandBy);
+ static 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/cmd/include/help.h b/hapsigntool_cpp/cmd/include/help.h
new file mode 100644
index 0000000000000000000000000000000000000000..43aaeee2b2ffd4ce6f465c3fab6f50953072b269
--- /dev/null
+++ b/hapsigntool_cpp/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/cmd/include/options.h b/hapsigntool_cpp/cmd/include/options.h
new file mode 100644
index 0000000000000000000000000000000000000000..f217a61257bc4ffa62ddf3047b1397cfa2f30087
--- /dev/null
+++ b/hapsigntool_cpp/cmd/include/options.h
@@ -0,0 +1,125 @@
+/*
+ * 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(const 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/cmd/include/params.h b/hapsigntool_cpp/cmd/include/params.h
new file mode 100644
index 0000000000000000000000000000000000000000..192dd538f6d2b7d31a46771d835859d11784fcd9
--- /dev/null
+++ b/hapsigntool_cpp/cmd/include/params.h
@@ -0,0 +1,53 @@
+/*
+ * 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:
+ static std::unordered_set InitParamField(const std::vector& paramFields);
+ static bool GetSignatureAlgorithm(const std::string& signatureAlgorithm, SignatureAlgorithmHelper& out);
+ Params() = default;
+ virtual ~Params() = default;
+ virtual std::string GetMethod();
+ virtual void SetMethod(const std::string& method);
+ virtual Options* GetOptions();
+
+private:
+ std::shared_ptr options = std::make_shared();
+
+private:
+ std::string method;
+};
+
+using ParamsSharedPtr = std::shared_ptr;
+
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_PARAMS_H
diff --git a/hapsigntool_cpp/cmd/include/params_run_tool.h b/hapsigntool_cpp/cmd/include/params_run_tool.h
new file mode 100644
index 0000000000000000000000000000000000000000..b84597828cb0539e6589d4a9f3c8424c05a09e16
--- /dev/null
+++ b/hapsigntool_cpp/cmd/include/params_run_tool.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_HAP_SIGN_TOOL_H
+#define SIGNATRUETOOLS_HAP_SIGN_TOOL_H
+
+#include
+#include
+#include
+
+#include "cmd_util.h"
+#include "sign_tool_service_impl.h"
+#include "signature_tools_log.h"
+#include "params_trust_list.h"
+#include "string_utils.h"
+
+namespace OHOS {
+namespace SignatureTools {
+class ParamsRunTool final {
+public:
+ ParamsRunTool() = delete;
+ static bool ProcessCmd(char** args, size_t size);
+ static bool DispatchParams(ParamsSharedPtr params, SignToolServiceImpl& api);
+ static bool CallGenerators(ParamsSharedPtr params, SignToolServiceImpl& api);
+ static bool RunKeypair(Options* params, SignToolServiceImpl& api);
+ static bool RunCa(Options* params, SignToolServiceImpl& api);
+ static bool RunCert(Options* params, SignToolServiceImpl& api);
+ static bool RunAppCert(Options* params, SignToolServiceImpl& api);
+ static bool RunProfileCert(Options* params, SignToolServiceImpl& api);
+ static bool RunCsr(Options* params, SignToolServiceImpl& api);
+ static bool RunSignProfile(Options* params, SignToolServiceImpl& api);
+ static bool RunSignApp(Options* params, SignToolServiceImpl& api);
+ static bool RunVerifyProfile(Options* params, SignToolServiceImpl& api);
+ static bool RunVerifyApp(Options* params, SignToolServiceImpl& api);
+ static bool CheckEndCertArguments(Options& params);
+ static bool CheckProfile(Options& params);
+ static void PrintHelp();
+ static void Version();
+
+public:
+ static std::vector InformList;
+
+private:
+ static const std::string VERSION;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif // SIGNATRUETOOLS_HAP_SIGN_TOOL_H
diff --git a/hapsigntool_cpp/cmd/include/params_trust_list.h b/hapsigntool_cpp/cmd/include/params_trust_list.h
new file mode 100644
index 0000000000000000000000000000000000000000..8d3da08c5dd21f72a875be74fa46e5a305cf7b87
--- /dev/null
+++ b/hapsigntool_cpp/cmd/include/params_trust_list.h
@@ -0,0 +1,46 @@
+/*
+ * 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_PARAMSTRUSTLIST_H
+#define SIGNATRUETOOLS_PARAMSTRUSTLIST_H
+
+#include
+#include
+#include
+#include
+#include
+#include "signature_tools_log.h"
+#include "hap_verify_result.h"
+
+namespace OHOS {
+namespace SignatureTools {
+class ParamsTrustList final {
+public:
+ static ParamsTrustList* GetInstance();
+ std::vector GetTrustList(const std::string& command);
+
+private:
+ void ReadHelpParam(std::istringstream& fd);
+ void PutTrustMap(const std::string& cmd_stand_by, const std::string& param);
+ void GenerateTrustList();
+
+private:
+ static std::unique_ptr paramTrustListInstance;
+ static std::mutex mtx;
+ std::unordered_map> trustMap;
+};
+} // namespace SignatureTools
+} // namespace OHOS
+#endif
diff --git a/hapsigntool_cpp/cmd/signature_tools_cmd.gni b/hapsigntool_cpp/cmd/signature_tools_cmd.gni
new file mode 100644
index 0000000000000000000000000000000000000000..16fdb14a45599b8325cf5db3bc619327aaf59f83
--- /dev/null
+++ b/hapsigntool_cpp/cmd/signature_tools_cmd.gni
@@ -0,0 +1,23 @@
+# Copyright (c) 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")
+signature_tools_cmd_include = [ "${signature_tools_cmd}/include" ]
+
+signature_tools_cmd_src = [
+ "${signature_tools_cmd}/src/cmd_util.cpp",
+ "${signature_tools_cmd}/src/params_run_tool.cpp",
+ "${signature_tools_cmd}/src/options.cpp",
+ "${signature_tools_cmd}/src/params_trust_list.cpp",
+ "${signature_tools_cmd}/src/params.cpp",
+]
diff --git a/hapsigntool_cpp/cmd/src/cmd_util.cpp b/hapsigntool_cpp/cmd/src/cmd_util.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e17b973f541acfee7f1e5149134409f87a1083af
--- /dev/null
+++ b/hapsigntool_cpp/cmd/src/cmd_util.cpp
@@ -0,0 +1,531 @@
+/*
+ * 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 "cmd_util.h"
+#include
+#include
+
+#include "params_run_tool.h"
+#include "constant.h"
+#include "param_constants.h"
+
+namespace OHOS {
+namespace SignatureTools {
+const std::regex INTEGER_PATTERN = std::regex("\\d{1,10}");
+
+bool CmdUtil::String2Bool(Options* options, const std::string& option)
+{
+ std::string val = options->GetString(option);
+ if (val == "1" || val == "true" || val == "TRUE") {
+ (*options)[option] = true;
+ } else if (val == "0" || val == "false" || val == "FALSE") {
+ (*options)[option] = false;
+ } else {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, val + "is not valid value for "+"-" + option);
+ return false;
+ }
+ return true;
+}
+
+static bool UpdateParamForVariantCertInt(ParamsSharedPtr param)
+{
+ int defualtValidity = 0;
+ Options* options = param->GetOptions();
+ if (options->count(Options::VALIDITY)) {
+ int validity = 0;
+ std::string val = options->GetString(Options::VALIDITY);
+ for (char x : val) {
+ if (!isdigit(x)) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "Invalid parameter '"
+ + val + "', You should fill in the numbers");
+ return false;
+ }
+ }
+ try {
+ validity = stoi(val);
+ }
+ catch (std::exception& e) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "Invalid parameter '"
+ + val + "', You should fill in the numbers");
+ return false;
+ }
+ validity *= ONE_DAY_TIME;
+ (*options)[Options::VALIDITY] = validity;
+ } else if (param->GetMethod() == GENERATE_CA || param->GetMethod() == GENERATE_APP_CERT ||
+ param->GetMethod() == GENERATE_PROFILE_CERT) {
+ defualtValidity = DEFAULT_VALIDITY_DAYS * ONE_DAY_TIME;
+ (*options)[Options::VALIDITY] = defualtValidity;
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ defualtValidity = DEFAULT_CUSTOM_VALIDITY_DAYS * ONE_DAY_TIME;
+ (*options)[Options::VALIDITY] = defualtValidity;
+ }
+ return true;
+}
+
+static bool UpdateParamForVariantInt(ParamsSharedPtr param)
+{
+ Options* options = param->GetOptions();
+ // general
+ if (options->count(Options::KEY_SIZE)) {
+ std::string keySize = options->GetString(Options::KEY_SIZE);
+ if (keySize == "NIST-P-256") {
+ (*options)[Options::KEY_SIZE] = NIST_P_256;
+ } else if (keySize == "NIST-P-384") {
+ (*options)[Options::KEY_SIZE] = NIST_P_384;
+ } else {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "not supported '" + keySize
+ + "' Key algorithms length");
+ return false;
+ }
+ }
+ if (options->count(Options::BASIC_CONSTRAINTS_PATH_LEN)) {
+ int basicConstraintsPathLen = 0;
+ std::string val = options->GetString(Options::BASIC_CONSTRAINTS_PATH_LEN);
+ try {
+ basicConstraintsPathLen = stoi(val);
+ }
+ catch (std::exception& e) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "Invalid parameter '"
+ + val + "', You should fill in the numbers");
+ return false;
+ }
+ (*options)[Options::BASIC_CONSTRAINTS_PATH_LEN] = basicConstraintsPathLen;
+ } else if (param->GetMethod() == GENERATE_CA || param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::BASIC_CONSTRAINTS_PATH_LEN] = DEFAULT_BASIC_CONSTRAINTS_PATH_LEN;
+ }
+ if (!UpdateParamForVariantCertInt(param)) {
+ return false;
+ }
+ return true;
+}
+
+static bool UpdateParamForVariantBoolKeyUsage(ParamsSharedPtr param)
+{
+ Options* options = param->GetOptions();
+
+ //The bool type is used only by the "generate-cert" module
+ if (options->count(Options::KEY_USAGE_CRITICAL)) {
+ if (!CmdUtil::String2Bool(options, Options::KEY_USAGE_CRITICAL)) {
+ return false;
+ }
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::KEY_USAGE_CRITICAL] = DEFAULT_KEY_USAGE_CRITICAL;
+ }
+
+ //The bool type is used only by the "generate-cert" module
+ if (options->count(Options::EXT_KEY_USAGE_CRITICAL)) {
+ if (!CmdUtil::String2Bool(options, Options::EXT_KEY_USAGE_CRITICAL)) {
+ return false;
+ }
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::EXT_KEY_USAGE_CRITICAL] = DEFAULT_EXT_KEY_USAGE_CRITICAL;
+ }
+ return true;
+}
+
+static bool UpdateParamForVariantBoolConstraints(ParamsSharedPtr param)
+{
+ Options* options = param->GetOptions();
+
+ //The bool type is used only by the "generate-cert" module
+ if (options->count(Options::BASIC_CONSTRAINTS)) {
+ if (!CmdUtil::String2Bool(options, Options::BASIC_CONSTRAINTS)) {
+ return false;
+ }
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::BASIC_CONSTRAINTS] = DEFAULT_BASIC_CONSTRAINTS;
+ }
+
+ //The bool type is used only by the "generate-cert" module
+ if (options->count(Options::BASIC_CONSTRAINTS_CRITICAL)) {
+ if (!CmdUtil::String2Bool(options, Options::BASIC_CONSTRAINTS_CRITICAL)) {
+ return false;
+ }
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::BASIC_CONSTRAINTS_CRITICAL] = DEFAULT_BASIC_CONSTRAINTS_CRITICAL;
+ }
+ return true;
+}
+
+static bool UpdateParamForVariantBoolProfileSigned(ParamsSharedPtr param)
+{
+ Options* options = param->GetOptions();
+
+ //The bool type is used only by the "sign-app" module
+ if (options->count(Options::PROFILE_SIGNED)) {
+ std::string val = options->GetString(Options::PROFILE_SIGNED);
+ if (val == "1" || val == "true" || val == "TRUE") {
+ (*options)[Options::PROFILE_SIGNED] = DEFAULT_PROFILE_SIGNED_1;
+ } else if (val == "0" || val == "false" || val == "FALSE") {
+ (*options)[Options::PROFILE_SIGNED] = DEFAULT_PROFILE_SIGNED_0;
+ } else {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ val + "is not valid value for "+"-" + Options::PROFILE_SIGNED);
+ return false;
+ }
+ } else if (param->GetMethod() == SIGN_APP) {
+ (*options)[Options::PROFILE_SIGNED] = DEFAULT_PROFILE_SIGNED_1;
+ }
+
+ //The bool type is used only by the "generate-cert" module
+ if (options->count(Options::BASIC_CONSTRAINTS_CA)) {
+ if (!CmdUtil::String2Bool(options, Options::BASIC_CONSTRAINTS_CA)) {
+ return false;
+ }
+ } else if (param->GetMethod() == GENERATE_CERT) {
+ (*options)[Options::BASIC_CONSTRAINTS_CA] = DEFAULT_BASIC_CONSTRAINTS_CA;
+ }
+ return true;
+}
+
+static bool outFilePath(Options* options)
+{
+ std::initializer_list outFileKeys = {
+ Options::OUT_FILE, Options::KEY_STORE_FILE,
+ Options::ISSUER_KEY_STORE_FILE,
+ Options::OUT_PROFILE, Options::OUT_CERT_CHAIN};
+
+ // check path directory is exists
+ for (auto& key : outFileKeys) {
+ if (options->count(key)) {
+ std::filesystem::path pat = options->GetString(key);
+ if (std::filesystem::is_directory(pat)) {
+ PrintErrorNumberMsg("FILE_NOT_FOUND", FILE_NOT_FOUND, "'" + std::string(pat.c_str())
+ + "' is a directory");
+ return false;
+ }
+ std::string parentPath = pat.parent_path();
+ if (!std::filesystem::exists(parentPath)) {
+ PrintErrorNumberMsg("IO_ERROR", IO_ERROR, "output file parent directory'"
+ + std::string(parentPath.c_str()) + "' not exist");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool UpdateParamForCheckFile(ParamsSharedPtr param)
+{
+ // check file exists
+ Options* options = param->GetOptions();
+ std::initializer_list inFileKeys = {
+ Options::IN_FILE,
+ Options::SUB_CA_CERT_FILE,
+ Options::CA_CERT_FILE,
+ Options::PROFILE_CERT_FILE,
+ Options::APP_CERT_FILE,
+ Options::PROFILE_FILE};
+ for (auto& key : inFileKeys) {
+ if (options->count(key) &&
+ !FileUtils::IsValidFile(options->GetString(key))) {
+ return false;
+ }
+ }
+ // check path exists
+ if (!outFilePath(options)) {
+ return false;
+ }
+ return true;
+}
+
+static bool UpdateParamForCheckSignAlg(ParamsSharedPtr param)
+{
+ // check signAlg
+ Options* options = param->GetOptions();
+ if (options->count(Options::SIGN_ALG)) {
+ std::string signAlg = options->GetString(Options::SIGN_ALG);
+ if (signAlg != SIGN_ALG_SHA256 && signAlg != SIGN_ALG_SHA384) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "'" + signAlg + "' parameter is incorrect");
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool UpdateParamForInform(ParamsSharedPtr param)
+{
+ // check sign_app verify_app inform
+ Options* options = param->GetOptions();
+ if (param->GetMethod() == SIGN_APP ||
+ param->GetMethod() == VERIFY_APP) {
+ if (options->count(Options::INFORM)) {
+ std::string inForm = options->GetString(Options::INFORM);
+ if (!StringUtils::ContainsCase(ParamsRunTool::InformList, inForm)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "parameter '" + inForm
+ + "' format error, Inform only support zip/elf/bin");
+ return false;
+ }
+ } else {
+ (*options)[Options::INFORM] = ZIP;
+ }
+ }
+ return true;
+}
+
+static bool UpdateParamForOutform(ParamsSharedPtr param)
+{
+ // check generate_app_cert generate_profile_cert
+ Options* options = param->GetOptions();
+ if (param->GetMethod() == GENERATE_APP_CERT ||
+ param->GetMethod() == GENERATE_PROFILE_CERT) {
+ if (options->count(Options::OUT_FORM)) {
+ std::string outForm = options->GetString(Options::OUT_FORM);
+ if (outForm != OUT_FORM_CERT && outForm != OUT_FORM_CERT_CHAIN) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "parameter '" + outForm
+ + "' format error, Outform only supprot cert/cerChain");
+ return false;
+ }
+ } else {
+ (*options)[Options::OUT_FORM] = OUT_FORM_CERT_CHAIN;
+ }
+ }
+ return true;
+}
+
+//Check "remoteSign" additional parameters are required
+static bool UpdateParamForCheckRemoteSignProfile(ParamsSharedPtr param)
+{
+ Options* options = param->GetOptions();
+ std::set signProfileRemoteParams{ParamConstants::PARAM_REMOTE_SERVER,
+ ParamConstants::PARAM_REMOTE_USERNAME,
+ ParamConstants::PARAM_REMOTE_USERPWD,
+ ParamConstants::PARAM_REMOTE_ONLINEAUTHMODE,
+ ParamConstants::PARAM_REMOTE_SIGNERPLUGIN};
+
+ if (param->GetMethod() == SIGN_PROFILE && options->count(Options::MODE) &&
+ options->GetString(Options::MODE) == REMOTE_SIGN) {
+ for (const std::string& key : signProfileRemoteParams) {
+ if (options->count(key) == 0) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "sign profile RemoteSign absence param '"
+ + key + "'");
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+static bool UpdateParam(ParamsSharedPtr param)
+{
+ if (!UpdateParamForVariantInt(param)) {
+ return false;
+ }
+ if (!UpdateParamForVariantBoolKeyUsage(param)) {
+ return false;
+ }
+ if (!UpdateParamForVariantBoolConstraints(param)) {
+ return false;
+ }
+ if (!UpdateParamForVariantBoolProfileSigned(param)) {
+ return false;
+ }
+ if (!UpdateParamForCheckFile(param)) {
+ return false;
+ }
+ if (!UpdateParamForCheckSignAlg(param)) {
+ return false;
+ }
+ if (!UpdateParamForInform(param)) {
+ return false;
+ }
+ if (!UpdateParamForOutform(param)) {
+ return false;
+ }
+ if (!UpdateParamForCheckRemoteSignProfile(param)) {
+ return false;
+ }
+ return true;
+}
+
+int CmdUtil::GetCommandParameterKey(const char strChar, std::string& strChars, std::vector& trustList,
+ std::string& keyStandBy)
+{
+ if (strChar == '-') {
+ bool isTrust = std::find(trustList.begin(), trustList.end(), strChars) != trustList.end();
+ if (!isTrust) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "There is no '"
+ + strChars + "' command for the trust list");
+ return RET_FAILED;
+ }
+ keyStandBy = strChars.substr(1);
+ } else {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "'" + strChars
+ + "' Parameters error, Param key - value must in pairs");
+ return RET_FAILED;
+ }
+
+ return RET_OK;
+}
+
+bool CmdUtil::Convert2Params(char** args, size_t size, const ParamsSharedPtr& param)
+{
+ param->SetMethod(args[1]);
+ std::string keyStandBy = "";
+ bool readKey = true;
+ std::vector trustList = ParamsTrustList::GetInstance()->GetTrustList(args[1]);
+ if (trustList.empty()) {
+ return false;
+ }
+ std::string strChars;
+ for (size_t i = 2; i < size; i++) {
+ if (readKey) {
+ strChars = args[i];
+ if (GetCommandParameterKey(args[i][0], strChars, trustList, keyStandBy) == RET_OK) {
+ readKey = false;
+ } else {
+ return false;
+ }
+ } else {
+ bool success = ValidAndPutParam(param, keyStandBy, args[i]);
+ if (success) {
+ keyStandBy = "";
+ readKey = true;
+ } else {
+ return false;
+ }
+ }
+ }
+ if (!readKey) {
+ PrintErrorNumberMsg("INVALIDPARAM_ERROR", INVALIDPARAM_ERROR,
+ "The last command-line parameters, value, cannot be omitted");
+ return false;
+ }
+ if (!UpdateParam(param)) {
+ return false;
+ }
+ return true;
+}
+
+bool CmdUtil::ValidAndPutParam(ParamsSharedPtr params, const std::string& key, char* value)
+{
+ std::string str = "Pwd";
+ bool result;
+ if (key.empty()) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ "The command-line parameter key cannot be empty");
+ result = false;
+ } else if (strlen(value) == 0) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ "The command-line parameter value cannot be empty");
+ result = false;
+ } else if (params->GetOptions()->count(key)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR,
+ "Duplicate command parameter are not allowed '" + key + "'");
+ result = false;
+ } else if (key.length() >= str.length() && key.substr(key.length() - INVALIDCHAR) == str) {
+ params->GetOptions()->emplace(key, value);
+ result = true;
+ } else {
+ params->GetOptions()->emplace(key, std::string(value));
+ result = true;
+ }
+ return result;
+}
+
+bool CmdUtil::JudgeAlgType(const std::string& keyAlg)
+{
+ if (keyAlg != "ECC") {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "not supported '" + keyAlg + "' Key algorithms");
+ return false;
+ }
+ return true;
+}
+
+bool CmdUtil::JudgeSize(const int size)
+{
+ if (size != NIST_P_256 && size != NIST_P_384) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "Keysize params is incorrect, Support only 256 or 384");
+ return false;
+ }
+ return true;
+}
+
+bool CmdUtil::JudgeSignAlgType(const std::string& signAlg)
+{
+ if (signAlg != SIGN_ALG_SHA256 && signAlg != SIGN_ALG_SHA384) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "not supported '" + signAlg + "' signature algorithm");
+ return false;
+ }
+ return true;
+}
+
+/**
+ * @tc.name: Test parameter function
+ * @tc.desc: Pass more than one parameter,but it needs to be in the parameter list.
+ * @tc.type: FUNC
+ */
+bool CmdUtil::VerifyTypes(const std::string& inputType)
+{
+ if (inputType.size() == 0) {
+ return false;
+ }
+ std::vector vecs = StringUtils::SplitString(inputType.c_str(), ',');
+ std::set sets;
+ sets.insert("digitalSignature");
+ sets.insert("nonRepudiation");
+ sets.insert("keyEncipherment");
+ sets.insert("dataEncipherment");
+ sets.insert("keyAgreement");
+ sets.insert("certificateSignature");
+ sets.insert("crlSignature");
+ sets.insert("encipherOnly");
+ sets.insert("decipherOnly");
+ for (const auto& val : vecs) {
+ if (sets.count(val) == 0) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ "Not support command param '" + val + "'");
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
+ * @tc.name: Test parameter function
+ * @tc.desc: Pass one parameter,but it needs to be in the parameter list.
+ * @tc.type: FUNC
+ */
+bool CmdUtil::VerifyType(const std::string& inputType)
+{
+ std::set sets;
+ sets.insert("clientAuthentication");
+ sets.insert("serverAuthentication");
+ sets.insert("codeSignature");
+ sets.insert("emailProtection");
+ sets.insert("smartCardLogin");
+ sets.insert("timestamp");
+ sets.insert("ocspSignature");
+ if (sets.count(inputType) == 0) {
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR,
+ "Not support command param '" + inputType + "'");
+ return false;
+ }
+ return true;
+}
+
+bool CmdUtil::VerifyType(const std::string& inputtype, const std::string& supportTypes)
+{
+ std::string firstStr = supportTypes.substr(0, supportTypes.find_last_of(","));
+ std::string secondStr = supportTypes.substr(supportTypes.find_first_of(",") + 1,
+ supportTypes.size() - supportTypes.find_first_of(","));
+ if (inputtype == firstStr || inputtype == secondStr) {
+ return true;
+ }
+ PrintErrorNumberMsg("COMMAND_PARAM_ERROR", COMMAND_PARAM_ERROR, "Not support command param '" + inputtype + "'");
+
+ return false;
+}
+} // namespace SignatureTools
+} // namespace OHOS
\ No newline at end of file
diff --git a/hapsigntool_cpp/cmd/src/options.cpp b/hapsigntool_cpp/cmd/src/options.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24a98b6df8d3819cb48383f8098049ac33ceb52b
--- /dev/null
+++ b/hapsigntool_cpp/cmd/src/options.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 "options.h"
+
+namespace OHOS {
+namespace SignatureTools {
+
+/* Initializes the static member constant. */
+const std::string Options::KEY_ALIAS = "keyAlias";
+const std::string Options::KEY_RIGHTS = "keyPwd";
+const std::string Options::KEY_ALG = "keyAlg";
+const std::string Options::KEY_SIZE = "keySize";
+const std::string Options::KEY_STORE_FILE = "keystoreFile";
+const std::string Options::KEY_STORE_RIGHTS = "keystorePwd";
+const std::string Options::ISSUER_KEY_ALIAS = "issuerKeyAlias";
+const std::string Options::ISSUER_KEY_RIGHTS = "issuerKeyPwd";
+const std::string Options::ISSUER_KEY_STORE_FILE = "issuerKeystoreFile";
+const std::string Options::ISSUER_KEY_STORE_RIGHTS = "issuerKeystorePwd";
+const std::string Options::ISSUER = "issuer";
+const std::string Options::SUBJECT = "subject";
+const std::string Options::VALIDITY = "validity";
+const std::string Options::SIGN_ALG = "signAlg";
+const std::string Options::BASIC_CONSTRAINTS_PATH_LEN = "basicConstraintsPathLen";
+const std::string Options::OUT_FILE = "outFile";
+const std::string Options::OUT_FORM = "outForm";
+const std::string Options::SUB_CA_CERT_FILE = "subCaCertFile";
+const std::string Options::CA_CERT_FILE = "rootCaCertFile";
+const std::string Options::IN_FILE = "inFile";
+const std::string Options::PROFILE_CERT_FILE = "profileCertFile";
+const std::string Options::APP_CERT_FILE = "appCertFile";
+const std::string Options::KEY_USAGE = "keyUsage";
+const std::string Options::EXT_KEY_USAGE = "extKeyUsage";
+const std::string Options::KEY_USAGE_CRITICAL = "keyUsageCritical";
+const std::string Options::EXT_KEY_USAGE_CRITICAL = "extKeyUsageCritical";
+const std::string Options::BASIC_CONSTRAINTS_CA = "basicConstraintsCa";
+const std::string Options::BASIC_CONSTRAINTS_CRITICAL = "basicConstraintsCritical";
+const std::string Options::BASIC_CONSTRAINTS = "basicConstraints";
+const std::string Options::OUT_FORM_SCOPE = "cert,certChain";
+const std::string Options::MODE = "mode";
+const std::string Options::INFORM = "inForm";
+const std::string Options::OUT_CERT_CHAIN = "outCertChain";
+const std::string Options::OUT_PROFILE = "outProfile";
+const std::string Options::PROOF_FILE = "outproof";
+const std::string Options::PROFILE_FILE = "profileFile";
+const std::string Options::PROFILE_SIGNED = "profileSigned";
+
+char* Options::GetChars(const std::string key)
+{
+ if (this->count(key) == 0) {
+ return nullptr;
+ }
+
+ auto value = (*this)[key];
+ char** charsPtr = std::get_if(&value);
+ if (charsPtr == nullptr) {
+ SIGNATURE_TOOLS_LOGI("GetChars key = %s value = nullptr !", key.c_str());
+ return nullptr;
+ }
+ return *charsPtr;
+}
+
+std::string Options::GetString(const std::string key)
+{
+ if (this->count(key) == 0) {
+ return "";
+ }
+
+ auto value = (*this)[key];
+ std::string* stringPtr = std::get_if(&value);
+ if (stringPtr == nullptr) {
+ SIGNATURE_TOOLS_LOGI("GetString key = %s value = """, key.c_str());
+ return "";
+ }
+ return *stringPtr;
+}
+
+std::string Options::GetString(const std::string key, std::string checkStr)
+{
+ if (this->count(key) == 0) {
+ return "";
+ }
+
+ auto value = (*this)[key];
+ std::string* stringPtr = std::get_if(&value);
+ if (stringPtr == nullptr || *stringPtr == "") {
+ SIGNATURE_TOOLS_LOGI("GetString key = %s value = %s ", key.c_str(), checkStr.c_str());
+ return checkStr;
+ }
+ return *stringPtr;
+}
+
+int Options::GetInt(const std::string key)
+{
+ if (this->count(key) == 0) {
+ return 0;
+ }
+
+ auto value = (*this)[key];
+ int* stringPtr = std::get_if(&value);
+ if (stringPtr == nullptr) {
+ SIGNATURE_TOOLS_LOGI("GetInt key = %s value = 0 ", key.c_str());
+ return 0;
+ }
+ return *stringPtr;
+}
+
+bool Options::Equals(const std::string key1, const std::string& key2)
+{
+ std::string ksFile = GetString(key1);
+ std::string iksFile = GetString(key2);
+ if (ksFile == iksFile) {
+ return true;
+ }
+ return false;
+}
+
+bool Options::Required(const std::initializer_list keys)
+{
+ for (auto& key : keys) {
+ if (!this->IsEmpty(key) && !(this->find(key) != this->end())) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "Params '-" + key + "' is required");
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Options::IsEmpty(std::string cs)
+{
+ if (cs.empty()) {
+ return true;
+ }
+ return false;
+}
+
+bool Options::GetBool(const std::string key)
+{
+ auto value = (*this)[key];
+ bool* stringPtr = std::get_if(&value);
+ return *stringPtr;
+}
+} // namespace SignatureTools
+} // namespace OHOS
\ No newline at end of file
diff --git a/hapsigntool_cpp/cmd/src/params.cpp b/hapsigntool_cpp/cmd/src/params.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..81819176cb811c6223728ada56808d47326e3df3
--- /dev/null
+++ b/hapsigntool_cpp/cmd/src/params.cpp
@@ -0,0 +1,57 @@
+/*
+ * 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 "params.h"
+
+namespace OHOS {
+namespace SignatureTools {
+std::string Params::GetMethod()
+{
+ return method;
+}
+
+void Params::SetMethod(const std::string& method)
+{
+ this->method = method;
+}
+
+Options* Params::GetOptions()
+{
+ return options.get();
+}
+
+std::unordered_set Params::InitParamField(const std::vector& paramFields)
+{
+ return std::unordered_set(paramFields.begin(), paramFields.end());
+}
+
+bool Params::GetSignatureAlgorithm(const std::string& signatureAlgorithm,
+ SignatureAlgorithmHelper& out)
+{
+ if (signatureAlgorithm == ParamConstants::HAP_SIG_ALGORITHM_SHA256_ECDSA) {
+ out = SignatureAlgorithmHelper::ECDSA_WITH_SHA256_INSTANCE;
+ return true;
+ } else if (signatureAlgorithm == ParamConstants::HAP_SIG_ALGORITHM_SHA384_ECDSA) {
+ out = SignatureAlgorithmHelper::ECDSA_WITH_SHA384_INSTANCE;
+ return true;
+ } else {
+ SIGNATURE_TOOLS_LOGE("get Signature Algorithm failed not support %s", signatureAlgorithm.c_str());
+ return false;
+ }
+ return true;
+}
+
+} // namespace SignatureTools
+} // namespace OHOS
\ No newline at end of file
diff --git a/hapsigntool_cpp/cmd/src/params_run_tool.cpp b/hapsigntool_cpp/cmd/src/params_run_tool.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d161a61f6ef9da56f154046b42b1a3d906160f6
--- /dev/null
+++ b/hapsigntool_cpp/cmd/src/params_run_tool.cpp
@@ -0,0 +1,401 @@
+/*
+ * 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 "params_run_tool.h"
+#include
+#include
+#include
+
+#include "constant.h"
+#include "help.h"
+
+namespace OHOS {
+namespace SignatureTools {
+const std::string ParamsRunTool::VERSION = "1.0.0";
+
+std::vector ParamsRunTool::InformList = {
+ "bin",
+ "elf",
+ "zip"
+};
+
+static std::unordered_map > DISPATCH_RUN_METHOD {
+ {SIGN_APP, ParamsRunTool::RunSignApp},
+ {SIGN_PROFILE, ParamsRunTool::RunSignProfile},
+ {VERIFY_APP, ParamsRunTool::RunVerifyApp},
+ {VERIFY_PROFILE, ParamsRunTool::RunVerifyProfile}
+};
+
+static std::unordered_map > GENERATOR_RUN_METHOD {
+ {GENERATE_KEYPAIR, ParamsRunTool::RunKeypair},
+ {GENERATE_CSR, ParamsRunTool::RunCsr},
+ {GENERATE_CA, ParamsRunTool::RunCa},
+ {GENERATE_APP_CERT, ParamsRunTool::RunAppCert},
+ {GENERATE_PROFILE_CERT, ParamsRunTool::RunProfileCert},
+ {GENERATE_CERT, ParamsRunTool::RunCert},
+};
+
+
+bool ParamsRunTool::ProcessCmd(char** args, size_t size)
+{
+ if (size < CmdUtil::ARGS_MIN_LEN) {
+ args[1] = const_cast("");
+ }
+ if (args == nullptr || strcmp(args[1], "") == 0) {
+ PrintHelp();
+ return true;
+ } else if (strcmp(args[1], "-h") == 0 || strcmp(args[1], "-help") == 0) {
+ PrintHelp();
+ return true;
+ } else if (strcmp(args[1], "-v") == 0 || strcmp(args[1], "-version") == 0) {
+ Version();
+ return true;
+ } else {
+ std::shared_ptr serviceApi = std::make_shared();
+ ParamsSharedPtr param = std::make_shared();
+ if (!CmdUtil::Convert2Params(args, size, param)) {
+ PrintMsg(param->GetMethod() + " failed");
+ return false;
+ }
+ PrintMsg("Start " + param->GetMethod());
+ SIGNATURE_TOOLS_LOGD("%s run start time ", param->GetMethod().c_str());
+ if (!DispatchParams(param, *serviceApi.get())) {
+ SIGNATURE_TOOLS_LOGD("%s run end time ", param->GetMethod().c_str());
+ PrintMsg(param->GetMethod() + " failed");
+ return false;
+ }
+ PrintMsg(param->GetMethod() + " success");
+ SIGNATURE_TOOLS_LOGD("%s run end time ", param->GetMethod().c_str());
+ }
+ return true;
+}
+
+bool ParamsRunTool::CallGenerators(ParamsSharedPtr params, SignToolServiceImpl& api)
+{
+ bool isSuccess = false;
+ std::string method = params->GetMethod();
+ if (GENERATOR_RUN_METHOD.count(method) == 0) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "Unsupported method: " + method);
+ return false;
+ } else {
+ isSuccess=GENERATOR_RUN_METHOD[method](params->GetOptions(), api);
+ }
+ return isSuccess;
+}
+
+bool ParamsRunTool::RunSignApp(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::MODE, Options::IN_FILE, Options::OUT_FILE, Options::SIGN_ALG})) {
+ return false;
+ }
+ std::string mode = params->GetString(Options::MODE);
+ if (!StringUtils::CaseCompare(mode, LOCAL_SIGN) &&
+ !StringUtils::CaseCompare(mode, REMOTE_SIGN)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "not support command param '" + mode + "'");
+ return false;
+ }
+ if (StringUtils::CaseCompare(mode, LOCAL_SIGN)) {
+ if (!params->Required({Options::KEY_STORE_FILE, Options::KEY_ALIAS, Options::APP_CERT_FILE})) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+ }
+ if (!CheckProfile(*params)) {
+ return false;
+ }
+ std::string inForm = params->GetString(Options::INFORM, ZIP);
+ if (!StringUtils::IsEmpty(inForm) && !StringUtils::ContainsCase(InformList, inForm)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "parameter '" + inForm
+ + "' format error, Inform only support zip/elf/bin");
+ return false;
+ }
+ std::string signAlg = params->GetString(Options::SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ return api.SignHap(params);
+}
+
+bool ParamsRunTool::CheckProfile(Options& params)
+{
+ std::string inForm = params.GetString(Options::INFORM);
+ std::string profileFile = params.GetString(Options::PROFILE_FILE);
+
+ std::string profileSigned = params.GetString(Options::PROFILE_SIGNED);
+ if (StringUtils::CaseCompare(inForm, ELF) && FileUtils::IsEmpty(profileFile)) {
+ return true;
+ }
+
+ if (profileSigned == "1") {
+ if (!FileUtils::ValidFileType(profileFile, {"p7b"})) {
+ return false;
+ }
+ } else {
+ if (!FileUtils::ValidFileType(profileFile, {"json"})) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ParamsRunTool::DispatchParams(ParamsSharedPtr params, SignToolServiceImpl& api)
+{
+ bool isSuccess = false;
+ std::string method = params->GetMethod();
+ if (DISPATCH_RUN_METHOD.count(method) == 0) {
+ isSuccess = ParamsRunTool::CallGenerators(params, api);
+ } else {
+ isSuccess = DISPATCH_RUN_METHOD[method](params->GetOptions(), api);
+ }
+ return isSuccess;
+}
+
+bool ParamsRunTool::RunCa(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::KEY_ALIAS, Options::KEY_ALG,
+ Options::KEY_SIZE, Options::SUBJECT, Options::SIGN_ALG, Options::KEY_STORE_FILE})) {
+ return false;
+ }
+ std::string keyAlg = params->GetString(Options::KEY_ALG);
+ if (!CmdUtil::JudgeAlgType(keyAlg)) {
+ return false;
+ }
+ int size = params->GetInt(Options::KEY_SIZE);
+ if (!CmdUtil::JudgeSize(size)) {
+ return false;
+ }
+ std::string signAlg = params->GetString(Options::SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+
+ return api.GenerateCA(params);
+}
+
+bool ParamsRunTool::RunCert(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::KEY_ALIAS, Options::ISSUER,
+ Options::ISSUER_KEY_ALIAS, Options::SUBJECT, Options::KEY_USAGE,
+ Options::SIGN_ALG, Options::KEY_STORE_FILE})) {
+ return false;
+ }
+ std::string keyusage = params->GetString(Options::KEY_USAGE);
+ if (!CmdUtil::VerifyTypes(keyusage)) {
+ return false;
+ }
+ std::string extkeyusage = params->GetString(Options::EXT_KEY_USAGE);
+ if (!extkeyusage.empty()) {
+ if (!CmdUtil::VerifyType(extkeyusage)) {
+ return false;
+ }
+ }
+ std::string signAlg = params->GetString(Options::SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+ return api.GenerateCert(params);
+}
+
+bool ParamsRunTool::CheckEndCertArguments(Options& params)
+{
+ if (!params.Required({params.KEY_ALIAS, params.ISSUER, params.ISSUER_KEY_ALIAS,
+ params.SUBJECT, params.SIGN_ALG, params.KEY_STORE_FILE})) {
+ return false;
+ }
+ std::string signAlg = params.GetString(params.SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ std::string outForm = params.GetString(params.OUT_FORM);
+ if (!outForm.empty()) {
+ if (!CmdUtil::VerifyType(outForm, Options::OUT_FORM_SCOPE)) {
+ return false;
+ }
+ }
+ if (!outForm.empty() && "certChain" == outForm) {
+ if (!params.Required({params.SUB_CA_CERT_FILE, params.CA_CERT_FILE})) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params.GetString(params.SUB_CA_CERT_FILE), {"cer"}) ||
+ !FileUtils::ValidFileType(params.GetString(params.CA_CERT_FILE), {"cer"})) {
+ return false;
+ }
+ }
+ std::string keyStoreFile = params.GetString(params.KEY_STORE_FILE);
+ if (!FileUtils::ValidFileType(keyStoreFile, {"p12", "jks"})) {
+ return false;
+ }
+ if (params.find(params.ISSUER_KEY_STORE_FILE) != params.end()) {
+ std::string issuerKeyStoreFile = params.GetString(params.ISSUER_KEY_STORE_FILE);
+ if (!FileUtils::ValidFileType(issuerKeyStoreFile, {"p12", "jks"})) {
+ return false;
+ }
+ }
+ std::string outFile = params.GetString(params.OUT_FILE);
+ if (!outFile.empty()) {
+ if (!FileUtils::ValidFileType(outFile, {"cer", "pem"})) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool ParamsRunTool::RunAppCert(Options* params, SignToolServiceImpl& api)
+{
+ if (!ParamsRunTool::CheckEndCertArguments(*params)) {
+ return false;
+ }
+ return api.GenerateAppCert(params);
+}
+
+bool ParamsRunTool::RunProfileCert(Options* params, SignToolServiceImpl& api)
+{
+ if (!ParamsRunTool::CheckEndCertArguments(*params)) {
+ return false;
+ }
+ return api.GenerateProfileCert(params);
+}
+
+bool ParamsRunTool::RunKeypair(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::KEY_ALIAS, Options::KEY_ALG, Options::KEY_SIZE, Options::KEY_STORE_FILE})) {
+ return false;
+ }
+ std::string keyAlg = params->GetString(Options::KEY_ALG);
+ if (!CmdUtil::JudgeAlgType(keyAlg)) {
+ return false;
+ }
+ int size = params->GetInt(Options::KEY_SIZE);
+ if (!CmdUtil::JudgeSize(size)) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+ return api.GenerateKeyStore(params);
+}
+
+bool ParamsRunTool::RunCsr(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::KEY_ALIAS, Options::SUBJECT, Options::SIGN_ALG, Options::KEY_STORE_FILE})) {
+ return false;
+ }
+ std::string signAlg = params->GetString(Options::SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+ if (params->count(Options::OUT_FILE)) {
+ if (!FileUtils::ValidFileType(params->GetString(Options::OUT_FILE), {"csr"})) {
+ return false;
+ }
+ }
+ return api.GenerateCsr(params);
+}
+
+bool ParamsRunTool::RunSignProfile(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({params->MODE, params->SIGN_ALG, params->OUT_FILE, params->IN_FILE})) {
+ return false;
+ }
+ std::string mode = params->GetString(Options::MODE);
+ if (!StringUtils::CaseCompare(mode, LOCAL_SIGN) &&
+ !StringUtils::CaseCompare(mode, REMOTE_SIGN)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "not support command param '" + mode + "'");
+ return false;
+ }
+ if (StringUtils::CaseCompare(mode, LOCAL_SIGN)) {
+ if (!params->Required({params->KEY_STORE_FILE, params->KEY_ALIAS, params->PROFILE_CERT_FILE})) {
+ return false;
+ }
+
+ if (!FileUtils::ValidFileType(params->GetString(Options::KEY_STORE_FILE), {"p12", "jks"})) {
+ return false;
+ }
+ }
+ std::string signAlg = params->GetString(Options::SIGN_ALG);
+ if (!CmdUtil::JudgeSignAlgType(signAlg)) {
+ return false;
+ }
+ std::string outFile = params->GetString(Options::OUT_FILE);
+ if (FileUtils::ValidFileType(outFile, {"p7b"}) == false) {
+ return false;
+ }
+ return api.SignProfile(params);
+}
+
+bool ParamsRunTool::RunVerifyProfile(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::IN_FILE})) {
+ return false;
+ }
+
+ if (!FileUtils::ValidFileType(params->GetString(Options::IN_FILE), {"p7b"})) {
+ return false;
+ }
+
+ std::string outFile = params->GetString(Options::OUT_FILE);
+ if (!outFile.empty()) {
+ if (!FileUtils::ValidFileType(outFile, {"json"})) {
+ return false;
+ }
+ }
+ return api.VerifyProfile(params);
+}
+
+void ParamsRunTool::PrintHelp()
+{
+ PrintMsg(HELP_TXT);
+}
+
+void ParamsRunTool::Version()
+{
+ PrintMsg(ParamsRunTool::VERSION);
+}
+
+bool ParamsRunTool::RunVerifyApp(Options* params, SignToolServiceImpl& api)
+{
+ if (!params->Required({Options::IN_FILE, Options::OUT_CERT_CHAIN, Options::OUT_PROFILE})) {
+ return false;
+ }
+ std::string inForm = params->GetString(Options::INFORM, ZIP);
+ if (!StringUtils::ContainsCase(InformList, inForm)) {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "parameter '" + inForm
+ + "' format error, Inform only support zip/elf/bin");
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::OUT_CERT_CHAIN), {"cer"})) {
+ return false;
+ }
+ if (!FileUtils::ValidFileType(params->GetString(Options::OUT_PROFILE), {"p7b"})) {
+ return false;
+ }
+ return api.VerifyHapSigner(params);
+}
+} // namespace SignatureTools
+} // namespace OHOS
\ No newline at end of file
diff --git a/hapsigntool_cpp/cmd/src/params_trust_list.cpp b/hapsigntool_cpp/cmd/src/params_trust_list.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..28ce5177e64eb9e0175bc2b39f5a64b2744cee90
--- /dev/null
+++ b/hapsigntool_cpp/cmd/src/params_trust_list.cpp
@@ -0,0 +1,111 @@
+/*
+ * 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 "params_trust_list.h"
+#include "constant.h"
+#include "params.h"
+#include "string_utils.h"
+#include "help.h"
+
+namespace OHOS {
+namespace SignatureTools {
+const std::string options = "[options]:";
+std::unique_ptr ParamsTrustList::paramTrustListInstance = nullptr;
+std::mutex ParamsTrustList::mtx;
+
+const std::vector commands = {
+ GENERATE_KEYPAIR + options,
+ GENERATE_CSR + options,
+ GENERATE_CERT + options,
+ GENERATE_CA + options,
+ GENERATE_APP_CERT + options,
+ GENERATE_PROFILE_CERT + options,
+ SIGN_PROFILE + options,
+ VERIFY_PROFILE + options,
+ SIGN_APP + options,
+ VERIFY_APP + options
+};
+
+ParamsTrustList* ParamsTrustList::GetInstance()
+{
+ if (!paramTrustListInstance) {
+ std::lock_guard lock(mtx);
+ if (!paramTrustListInstance) {
+ paramTrustListInstance = std::make_unique();
+ }
+ }
+
+ return paramTrustListInstance.get();
+}
+
+void ParamsTrustList::PutTrustMap(const std::string& cmdStandBy, const std::string& param)
+{
+ if (param.at(0) == '-') {
+ size_t pos = param.find(':');
+ std::string subParam = param.substr(0, pos);
+ subParam = StringUtils::Trim(subParam);
+ bool isExists = false;
+ if (trustMap.find(cmdStandBy) != trustMap.end()) {
+ isExists = true;
+ }
+ std::vector trustList = isExists ? trustMap[cmdStandBy] : std::vector();
+ trustList.push_back(subParam);
+ trustMap[cmdStandBy] = trustList;
+ }
+}
+
+void ParamsTrustList::ReadHelpParam(std::istringstream& fd)
+{
+ std::string str;
+ std::string cmdStandBy;
+ while (std::getline(fd, str)) {
+ bool isExists = false;
+ std::string params = StringUtils::Trim(str);
+ if (params.empty()) {
+ continue;
+ }
+ for (const auto& it : commands) {
+ if (it == params) {
+ cmdStandBy = params;
+ isExists = true;
+ break;
+ }
+ }
+ if (!isExists) {
+ PutTrustMap(cmdStandBy, params);
+ }
+ }
+}
+
+void ParamsTrustList::GenerateTrustList()
+{
+ std::istringstream iss(HELP_TXT);
+ ReadHelpParam(iss);
+}
+
+std::vector ParamsTrustList::GetTrustList(const std::string& command)
+{
+ std::string keyParam = command + options;
+ GenerateTrustList();
+ if (trustMap.find(keyParam) != trustMap.end()) {
+ return trustMap[keyParam];
+ } else {
+ PrintErrorNumberMsg("COMMAND_ERROR", COMMAND_ERROR, "'" + command + "is not trust command");
+ trustMap[keyParam].clear();
+ return trustMap[keyParam];
+ }
+}
+} // namespace SignatureTools
+} // namespace OHOS
\ No newline at end of file
diff --git a/hapsigntool_cpp/codesigning/datastructure/include/code_sign_block.h b/hapsigntool_cpp/codesigning/datastructure/include/code_sign_block.h
new file mode 100644
index 0000000000000000000000000000000000000000..b02481498a2267f32c763c5fe5b30f83711e4843
--- /dev/null
+++ b/hapsigntool_cpp/codesigning/datastructure/include/code_sign_block.h
@@ -0,0 +1,68 @@
+/*
+ * 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_CODE_SIGN_BLOCK_H
+#define SIGNATRUETOOLS_CODE_SIGN_BLOCK_H
+
+#include