From 7204501df330ac304ddb0453bdb9f69424200e5f Mon Sep 17 00:00:00 2001 From: yang1946 Date: Mon, 29 Apr 2024 17:29:45 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0tdd=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E7=94=A8=E4=BE=8B=E6=8F=90=E5=8D=87=E8=A6=86=E7=9B=96=E7=8E=87?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: yang1946 --- test/unittest/BUILD.gn | 3 + test/unittest/local_code_sign_utils_test.cpp | 40 ++++++- test/unittest/mock/include/hks_api.h | 44 ++++++++ .../mock/include/hks_api_mock_helper.h | 34 ++++++ test/unittest/mock/src/hks_api.cpp | 72 +++++++++++++ .../unittest/mock/src/hks_api_mock_helper.cpp | 101 ++++++++++++++++++ 6 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 test/unittest/mock/include/hks_api.h create mode 100644 test/unittest/mock/include/hks_api_mock_helper.h create mode 100644 test/unittest/mock/src/hks_api.cpp create mode 100644 test/unittest/mock/src/hks_api_mock_helper.cpp diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index ec2acca..4e88764 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -105,10 +105,13 @@ ohos_unittest("local_code_sign_utils_unittest") { "${code_signature_root_dir}/services/local_code_sign/src/local_sign_key.cpp", "${code_signature_root_dir}/utils/src/cert_utils.cpp", "local_code_sign_utils_test.cpp", + "mock/src/hks_api.cpp", + "mock/src/hks_api_mock_helper.cpp", ] deps = [ "${code_signature_root_dir}/interfaces/innerkits/code_sign_utils:libcode_sign_utils" ] include_dirs = [ + "mock/include", "utils/include", "${code_signature_root_dir}/services/local_code_sign/include", ] diff --git a/test/unittest/local_code_sign_utils_test.cpp b/test/unittest/local_code_sign_utils_test.cpp index afdb63e..c9c8b8a 100644 --- a/test/unittest/local_code_sign_utils_test.cpp +++ b/test/unittest/local_code_sign_utils_test.cpp @@ -47,7 +47,7 @@ public: /** * @tc.name: LocalCodeSignUtilsTest_0001 - * @tc.desc: Used to increase utils coverage + * @tc.desc: Sign local code successfully, owner ID is empty * @tc.type: Func * @tc.require: issueI8FCGF */ @@ -64,7 +64,43 @@ HWTEST_F(LocalCodeSignUtilsTest, LocalCodeSignUtilsTest_0001, TestSize.Level0) ByteBuffer signature; int ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), digest, signature); - EXPECT_EQ(ret, CS_ERR_HUKS_OBTAIN_CERT); + EXPECT_EQ(ret, CS_SUCCESS); +} + +/** + * @tc.name: LocalCodeSignUtilsTest_0002 + * @tc.desc: Sign local code with owner ID successfully + * @tc.type: Func + * @tc.require: issueI88PPA + */ +HWTEST_F(LocalCodeSignUtilsTest, LocalCodeSignUtilsTest_0002, TestSize.Level0) +{ + ByteBuffer digest; + std::string realPath; + std::string ownerID = "AppName123"; + bool bRet = OHOS::PathToRealPath(DEMO_AN_PATH2, realPath); + EXPECT_EQ(bRet, true); + bRet = FsverityUtilsHelper::GetInstance().GenerateFormattedDigest(realPath.c_str(), digest); + EXPECT_EQ(bRet, true); + + ByteBuffer signature; + int ret = PKCS7Generator::GenerateSignature(ownerID, LocalSignKey::GetInstance(), DEFAULT_HASH_ALGORITHM.c_str(), + digest, signature); + EXPECT_EQ(ret, CS_SUCCESS); +} + +/** + * @tc.name: LocalCodeSignUtilsTest_0003 + * @tc.desc: Generate formatted digest failed with wrong path + * @tc.type: Func + * @tc.require: issueI8FCGF + */ +HWTEST_F(LocalCodeSignUtilsTest, LocalCodeSignUtilsTest_0003, TestSize.Level0) +{ + ByteBuffer digest; + std::string realPath = DEMO_AN_PATH2 + "invalid"; + bool bRet = FsverityUtilsHelper::GetInstance().GenerateFormattedDigest(realPath.c_str(), digest); + EXPECT_EQ(bRet, false); } } // namespace CodeSign } // namespace Security diff --git a/test/unittest/mock/include/hks_api.h b/test/unittest/mock/include/hks_api.h new file mode 100644 index 0000000..fa509f1 --- /dev/null +++ b/test/unittest/mock/include/hks_api.h @@ -0,0 +1,44 @@ +/* + * 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. + */ + +#ifndef HKS_API_H +#define HKS_API_H + +#include "hks_type.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +int32_t HksKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet); + +int32_t HksAttestKey(const struct HksBlob *keyAlias, + const struct HksParamSet *paramSet, struct HksCertChain *certChain); + +int32_t HksGenerateKey(const struct HksBlob *keyAlias, + const struct HksParamSet *paramSetIn, struct HksParamSet *paramSetOut); + +int32_t HksInit(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksBlob *handle, struct HksBlob *token); + +int32_t HksUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData); + +int32_t HksFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData); +} +} +} + +#endif /* HKS_API_H */ diff --git a/test/unittest/mock/include/hks_api_mock_helper.h b/test/unittest/mock/include/hks_api_mock_helper.h new file mode 100644 index 0000000..8634e5d --- /dev/null +++ b/test/unittest/mock/include/hks_api_mock_helper.h @@ -0,0 +1,34 @@ +/* + * 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. + */ + +#ifndef HKS_API_MOCK_HELPER_H +#define HKS_API_MOCK_HELPER_H + +#include +#include +#include +#include + +#include "log.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { + bool PemToDer(const char *pemData, const uint32_t size, uint8_t *derData, uint32_t derLen); + bool GetCertInDer(uint8_t *derData, uint32_t derLen); +} +} +} +#endif /* HKS_API_MOCK_HELPER_H */ diff --git a/test/unittest/mock/src/hks_api.cpp b/test/unittest/mock/src/hks_api.cpp new file mode 100644 index 0000000..828acb3 --- /dev/null +++ b/test/unittest/mock/src/hks_api.cpp @@ -0,0 +1,72 @@ +/* + * 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. + */ + +#include "hks_api.h" + +#include "hks_api_mock_helper.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +int32_t HksKeyExist(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet) +{ + LOG_INFO("Mock HksKeyExist"); + return HKS_SUCCESS; +} + +int32_t HksAttestKey(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksCertChain *certChain) +{ + LOG_INFO("Mock HksAttestKey"); + + bool ret = GetCertInDer(certChain->certs[0].data, certChain->certs[0].size); + if (!ret) { + LOG_ERROR("Failed to convert PEM to DER.\n"); + return HKS_FAILURE; + } + return HKS_SUCCESS; +} + +int32_t HksGenerateKey(const struct HksBlob *keyAlias, + const struct HksParamSet *paramSetIn, struct HksParamSet *paramSetOut) +{ + LOG_INFO("Mock HksGenerateKey"); + return HKS_SUCCESS; +} + +int32_t HksInit(const struct HksBlob *keyAlias, const struct HksParamSet *paramSet, + struct HksBlob *handle, struct HksBlob *token) +{ + LOG_INFO("Mock HksInit"); + return HKS_SUCCESS; +} + + +int32_t HksUpdate(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + LOG_INFO("Mock HksUpdate"); + return HKS_SUCCESS; +} + +int32_t HksFinish(const struct HksBlob *handle, const struct HksParamSet *paramSet, + const struct HksBlob *inData, struct HksBlob *outData) +{ + LOG_INFO("Mock HksFinish"); + return HKS_SUCCESS; +} +} +} +} \ No newline at end of file diff --git a/test/unittest/mock/src/hks_api_mock_helper.cpp b/test/unittest/mock/src/hks_api_mock_helper.cpp new file mode 100644 index 0000000..b08bdf6 --- /dev/null +++ b/test/unittest/mock/src/hks_api_mock_helper.cpp @@ -0,0 +1,101 @@ +/* + * 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. + */ + +#include "hks_api_mock_helper.h" + +namespace OHOS { +namespace Security { +namespace CodeSign { +static const uint32_t CERT_DATA_SIZE = 8192; +static const std::string EFFECTIVE_PEM_DATA = + "-----BEGIN CERTIFICATE-----\n" + "MIIDgzCCAm2gAwIBAgIBATALBgkqhkiG9w0BAQswfzELMAkGA1UEBhMCQ04xEzAR\n" + "BgNVBAgMCmhlbGxvd29ybGQxEzARBgNVBAoMCmhlbGxvd29ybGQxEzARBgNVBAsM\n" + "CmhlbGxvd29ybGQxFjAUBgNVBAMMDWhlbGxvd29ybGQxMTExGTAXBgkqhkiG9w0B\n" + "CQEWCmhlbGxvd29ybGQwHhcNMjQwNDI1MTM0NzI0WhcNMzQwNDI1MTM0NzI0WjAa\n" + "MRgwFgYDVQQDEw9BIEtleW1hc3RlciBLZXkwWTATBgcqhkjOPQIBBggqhkjOPQMB\n" + "BwNCAAS2Ke53DuesDI11IflM1ewmsMgmFODEWo91i3rJ1DN00XkDZWnbpPBC4vTU\n" + "ghEBJyaL0Llf8sAnOIhREXd9F3VIo4IBPDCCATgwCwYDVR0PBAQDAgeAMAgGA1Ud\n" + "HwQBADCCAR0GDCsGAQQBj1sCgngBAwSCAQswggEHAgEAMDQCAQAGDSsGAQQBj1sC\n" + "gngCAQQEIL1Mz84BeHuSz7BXsT7VV13vY+yHxj3bHm04Ts5FUzJbMCICAQIGDSsG\n" + "AQQBj1sCgngCAQIEDkxPQ0FMX1NJR05fS0VZMFwCAQIGDSsGAQQBj1sCgngCAQMw\n" + "SAYOKwYBBAGPWwKCeAIBAwEENnsicHJvY2Vzc05hbWUiOiJsb2NhbF9jb2RlX3Np\n" + "Z24iLCJBUEwiOiJzeXN0ZW1fYmFzaWMifTAYAgECBg0rBgEEAY9bAoJ4AgELBAQA\n" + "AAAAMBgCAQIGDSsGAQQBj1sCgngCAQUEBAIAAAAwFgIBAgYOKwYBBAGPWwKCeAIE\n" + "AQUBAf8wCwYJKoZIhvcNAQELA4IBAQB/VnD1eZWph2/JcQU4QFvdn0P1xrbsT3XP\n" + "dcIG4q3qWbrMBSq3DVmMWj3GZS+P+kW/Ni/ArnOzt/rUrui37yYWYylFOq9hBxcf\n" + "Q9tSPOgXcB6EuxKF4O0mw7lS3rsvUaPtEG299ggV2UzkTmw8T+nX3OvUt5f7VN4i\n" + "GY9u5Ou8DJNgr3gsF7Y1NaoC3zmnh9vAN03rUOWRBbCejf8hG6OY77TMaNIdfwwk\n" + "1kM3ZM0+dUfKaKjU767kxPYdAbxrp9zGCd3Nu3B9WqJIz/RD+JaZGhugY6rrQZ6S\n" + "ipcaNXzDYm10ccKjm/CSXoxE5PDikiUnK1vLUOPb6w3akQxwFOgZ\n" + "-----END CERTIFICATE-----\n"; + +bool PemToDer(const char *pemData, const uint32_t size, uint8_t *derData, uint32_t derLen) +{ + if (pemData == nullptr) { + LOG_ERROR("PemData is nullptr"); + return false; + } + + if (derData == nullptr) { + LOG_ERROR("Transferred in after malloc derData address."); + return false; + } + + if (derLen != CERT_DATA_SIZE) { + LOG_ERROR("The length of derData is not equal to %{public}d", derLen); + return false; + } + + BIO *mem = BIO_new_mem_buf(pemData, size); + if (mem == nullptr) { + LOG_ERROR("Fail to create bio for cert."); + return false; + } + + X509 *x509 = PEM_read_bio_X509(mem, nullptr, 0, nullptr); + if (x509 == nullptr) { + LOG_ERROR("Fail to read bio"); + BIO_free(mem); + return false; + } + + uint8_t *derTemp = nullptr; + int32_t derTempLen = i2d_X509(x509, &derTemp); + if (derTempLen < 0) { + X509_free(x509); + BIO_free(mem); + return false; + } + + if (memcpy_s(derData, derLen, derTemp, static_cast(derTempLen)) != EOK) { + LOG_ERROR("Memcpy failed"); + return false; + } + + X509_free(x509); + BIO_free(mem); + OPENSSL_free(derTemp); + + return true; +} + +bool GetCertInDer(uint8_t *derData, uint32_t derLen) +{ + return PemToDer(EFFECTIVE_PEM_DATA.c_str(), EFFECTIVE_PEM_DATA.size(), derData, derLen); +} +} +} +} \ No newline at end of file -- Gitee