diff --git a/bundle.json b/bundle.json index aee20468fc6b1cf0d8f7bd5b4e718fdfa40ba301..d3739da58f55fbd32c31ffcc402536d3cbcf3549 100644 --- a/bundle.json +++ b/bundle.json @@ -37,6 +37,7 @@ "common_event_service", "data_share", "device_auth", + "device_certificate_manager", "device_info_manager", "dsoftbus", "eventhandler", @@ -45,6 +46,7 @@ "hisysevent", "hitrace", "hilog", + "huks", "init", "ipc", "json", diff --git a/common/include/dm_constants.h b/common/include/dm_constants.h index 9de251c6365bc713ed1d9eb36234aac87333dd1f..f9525bf8cd215c02bf606d99ae9d914e388eb8a3 100755 --- a/common/include/dm_constants.h +++ b/common/include/dm_constants.h @@ -182,6 +182,7 @@ extern const char* DM_VERSION_5_0_3; extern const char* DM_VERSION_5_0_4; extern const char* DM_VERSION_5_0_5; extern const char* DM_VERSION_5_1_0; +extern const char* DM_VERSION_5_1_1; extern const char* DM_CURRENT_VERSION; extern const char* DM_VERSION_5_0_OLD_MAX; // Estimated highest version number of the old version } // namespace DistributedHardware diff --git a/common/include/dm_error_type.h b/common/include/dm_error_type.h index fd1873e55c76ed498e9f07d59921ddc12f275917..d427c4c9417e4698468ad3e5d230bbb65d55f1c4 100644 --- a/common/include/dm_error_type.h +++ b/common/include/dm_error_type.h @@ -136,6 +136,9 @@ enum { ERR_DM_PARSE_MESSAGE_FAILED = 969298348, ERR_DM_GET_BMS_FAILED = 969298349, ERR_DM_GET_BUNDLE_NAME_FAILED = 969298349, + ERR_DM_DESERIAL_CERT_FAILED = 969298350, + ERR_DM_VERIFY_CERT_FAILED = 969298351, + ERR_DM_GET_PARAM_FAILED = 969298352, }; } // namespace DistributedHardware } // namespace OHOS diff --git a/common/src/dm_constants.cpp b/common/src/dm_constants.cpp index feb239eed4afd269976590c77991fc84dab9f9f0..35904bddfc8a06e101f897661254f529d51794f6 100644 --- a/common/src/dm_constants.cpp +++ b/common/src/dm_constants.cpp @@ -170,6 +170,7 @@ const char* DM_VERSION_5_0_3 = "5.0.3"; const char* DM_VERSION_5_0_4 = "5.0.4"; const char* DM_VERSION_5_0_5 = "5.0.5"; const char* DM_VERSION_5_1_0 = "5.1.0"; +const char* DM_VERSION_5_1_1 = "5.1.1"; const char* DM_CURRENT_VERSION = DM_VERSION_5_1_0; const char* DM_VERSION_5_0_OLD_MAX = "5.0.99"; // Estimated highest version number of the old version } // namespace DistributedHardware diff --git a/sa_profile/device_manager.cfg b/sa_profile/device_manager.cfg index 35104cf5a1db49e5eda5f80e06b69a4e6cc56d84..a1aaa5e7c5e2db98727470ee57e5442fcba99bb4 100644 --- a/sa_profile/device_manager.cfg +++ b/sa_profile/device_manager.cfg @@ -40,11 +40,14 @@ "ohos.permission.ALLOW_CONNECT_CAR", "ohos.permission.ACCESS_SERVICE_DP", "ohos.permission.ACCESS_SENSING_WITH_ULTRASOUND", - "ohos.permission.ACCESS_DEVAUTH_CRED_PRIVILEGE" + "ohos.permission.ACCESS_DEVAUTH_CRED_PRIVILEGE", + "ohos.permission.ACCESS_IDS", + "ohos.permission.sec.ACCESS_UDID" ], "permission_acls" : [ "ohos.permission.MANAGE_SOFTBUS_NETWORK", - "ohos.permission.ACCESS_DEVAUTH_CRED_PRIVILEGE" + "ohos.permission.ACCESS_DEVAUTH_CRED_PRIVILEGE", + "ohos.permission.ACCESS_IDS" ], "jobs" : { "on-start" : "service:device_manager" diff --git a/services/implementation/BUILD.gn b/services/implementation/BUILD.gn index d3ec32d9276f7625fa09d92f70996013709daf43..0efccf0662b4b7faae4e4c19e55b227c0bb5d173 100644 --- a/services/implementation/BUILD.gn +++ b/services/implementation/BUILD.gn @@ -114,6 +114,7 @@ if (defined(ohos_lite)) { "include", "include/config", "include/adapter", + "include/attest", "include/authentication", "include/authentication_v2", "include/ability", @@ -269,6 +270,18 @@ if (defined(ohos_lite)) { external_deps += [ "spatial_awareness:spatial_awareness_client" ] } + if (!device_manager_common) { + sources += [ + "src/attest/dm_auth_attest_common.cpp", + "src/attest/dm_auth_generate_attest.cpp", + "src/attest/dm_auth_validate_attest.cpp", + ] + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } + subsystem_name = "distributedhardware" part_name = "device_manager" diff --git a/services/implementation/include/attest/dm_auth_attest_common.h b/services/implementation/include/attest/dm_auth_attest_common.h new file mode 100644 index 0000000000000000000000000000000000000000..2e42f5a8928b85ea615d44f209dc9c47caf33f05 --- /dev/null +++ b/services/implementation/include/attest/dm_auth_attest_common.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_ATTEST_COMMON_H +#define OHOS_DM_AUTH_ATTEST_COMMON_H + +#define DM_CERTS_COUNT 4 +#define UDID_BUF_LEN 65 +#define DM_CERTIFICATE_SIZE 8192 + +#include +#include + +#include "dm_anonymous.h" +#include "dm_auth_manager_base.h" +#include "dm_crypto.h" +#include "dm_random.h" +#include "json_object.h" + +namespace OHOS { +namespace DistributedHardware { + +typedef struct DmBlob { + uint32_t size; + uint8_t *data; +} DmBlob; + +typedef struct DmCertChain { + DmBlob *cert; + uint32_t certCount; +} DmCertChain; + +class AuthAttestCommon { +public: + static AuthAttestCommon &GetInstance(void) + { + static AuthAttestCommon instance; + return instance; + } + + std::string SerializeDmCertChain(const DmCertChain *chain); + bool DeserializeDmCertChain(const std::string &data, DmCertChain *outChain); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_ATTEST_COMMON_H \ No newline at end of file diff --git a/services/implementation/include/attest/dm_auth_generate_attest.h b/services/implementation/include/attest/dm_auth_generate_attest.h new file mode 100644 index 0000000000000000000000000000000000000000..292084079d4405ee1615341273352b0f76b294f8 --- /dev/null +++ b/services/implementation/include/attest/dm_auth_generate_attest.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_GENERATE_ATTEST_H +#define OHOS_DM_AUTH_GENERATE_ATTEST_H + +#include "dm_auth_attest_common.h" + +#include "dcm_api.h" +#include "dcm_type.h" + +namespace OHOS { +namespace DistributedHardware { +class AuthGenerateAttest { +public: + static AuthGenerateAttest &GetInstance(void) + { + static AuthGenerateAttest instance; + return instance; + } + + int32_t GenerateCertificate(DmCertChain &dmCertChain); + int32_t ConvertDcmCertChainToDmCertChain(DcmCertChain &dcmCertChain, DmCertChain &dmCertChain); + int32_t InitCertChain(DcmCertChain *certChain); + void FreeCertChain(DcmCertChain *chain); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_GENERATE_ATTEST_H \ No newline at end of file diff --git a/services/implementation/include/attest/dm_auth_validate_attest.h b/services/implementation/include/attest/dm_auth_validate_attest.h new file mode 100644 index 0000000000000000000000000000000000000000..7ae04ed2f968348422d39c7e117a71e874d27611 --- /dev/null +++ b/services/implementation/include/attest/dm_auth_validate_attest.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 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 OHOS_DM_AUTH_VALIDATE_ATTEST_H +#define OHOS_DM_AUTH_VALIDATE_ATTEST_H + +#include "dm_auth_attest_common.h" + +#include "hks_api.h" +#include "hks_param.h" +#include "hks_type.h" + +namespace OHOS { +namespace DistributedHardware { +class AuthValidateAttest { +public: + static AuthValidateAttest &GetInstance(void) + { + static AuthValidateAttest instance; + return instance; + } + + int32_t VerifyCertificate(DmCertChain &dmCertChain, const char *deviceUdid); + int32_t ConvertDmCertChainToHksCertChain(DmCertChain &dmCertChain, HksCertChain &hksCertChain); + int32_t FillHksParamSet(struct HksParamSet **paramSet, struct HksParam *param, int32_t paramNums); + void FreeHksCertChain(HksCertChain &chain); +}; +} // namespace DistributedHardware +} // namespace OHOS +#endif // OHOS_DM_AUTH_VALIDATE_ATTEST_H \ No newline at end of file diff --git a/services/implementation/include/authentication_v2/dm_auth_context.h b/services/implementation/include/authentication_v2/dm_auth_context.h index 71e5d3f4573165ef3eb565000a73c7c58b9d70ee..faf47baa267731adacb7dbbfd59fdeaf9bfebff6 100644 --- a/services/implementation/include/authentication_v2/dm_auth_context.h +++ b/services/implementation/include/authentication_v2/dm_auth_context.h @@ -171,6 +171,8 @@ struct DmAccess { std::string oldBundleName; // construct for old version compatible end std::string extraInfo; // Expandable field, JSON format, KV structure + std::string cert; + bool isCommonFlag{false}; }; struct DmAuthContext { diff --git a/services/implementation/include/authentication_v2/dm_auth_manager_base.h b/services/implementation/include/authentication_v2/dm_auth_manager_base.h index e19793aa6715d34c30bd15143cc1ef228bcb146f..923379717bf71cf40f4907b38ae7284554189de7 100644 --- a/services/implementation/include/authentication_v2/dm_auth_manager_base.h +++ b/services/implementation/include/authentication_v2/dm_auth_manager_base.h @@ -75,6 +75,10 @@ extern const char* WAIT_NEGOTIATE_TIMEOUT_TASK; extern const char* ADD_TIMEOUT_TASK; extern const char* WAIT_SESSION_CLOSE_TIMEOUT_TASK; extern const char* CLOSE_SESSION_TASK_SEPARATOR; +extern const char* TAG_DM_CERT_CHAIN; +extern const char* TAG_CERT_COUNT; +extern const char* TAG_CERT; +extern const char* TAG_IS_COMMON_FLAG; extern const int32_t AUTHENTICATE_TIMEOUT; extern const int32_t CONFIRM_TIMEOUT; diff --git a/services/implementation/include/authentication_v2/dm_auth_message_processor.h b/services/implementation/include/authentication_v2/dm_auth_message_processor.h index 88dbc2f8fbe12439acf28bc598b4d29b9925a707..0183ac5597ce1e6a6c9ab0ad6345cf74632210c6 100644 --- a/services/implementation/include/authentication_v2/dm_auth_message_processor.h +++ b/services/implementation/include/authentication_v2/dm_auth_message_processor.h @@ -321,6 +321,7 @@ private: bool CheckAccessValidityAndAssign(std::shared_ptr &context, DmAccess &access, DmAccess &accessTmp); void ParseUltrasonicSide(const JsonObject &jsonObject, std::shared_ptr context); + void ParseCert(const JsonObject &jsonObject, std::shared_ptr context); std::shared_ptr cryptoMgr_ = nullptr; std::unordered_map createMessageFuncMap_; std::unordered_map paraseMessageFuncMap_; diff --git a/services/implementation/src/attest/dm_auth_attest_common.cpp b/services/implementation/src/attest/dm_auth_attest_common.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6db2d3d528126d9a5a43ecfcda895f8f49d6d4f1 --- /dev/null +++ b/services/implementation/src/attest/dm_auth_attest_common.cpp @@ -0,0 +1,142 @@ +/* +* Copyright (c) 2025 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 "dm_auth_attest_common.h" + +#include "dm_error_type.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +const int32_t MAX_CERT_COUNT = 1024; +constexpr int32_t HEX_TO_UINT8 = 2; + +std::string AuthAttestCommon::SerializeDmCertChain(const DmCertChain *chain) +{ + if (chain == nullptr || chain->cert == nullptr || chain->certCount == 0) { + return "{}"; + } + JsonObject jsonObject; + jsonObject[TAG_CERT_COUNT] = chain->certCount; + JsonObject jsonArrayObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + for (uint32_t i = 0; i < chain->certCount; ++i) { + const DmBlob &blob = chain->cert[i]; + if (blob.data == nullptr || blob.size == 0) { + return "{}"; + } + const uint32_t hexLen = blob.size * HEX_TO_UINT8 + 1; // 2*blob.size + 1 + char *hexBuffer = new char[hexLen]{0}; + if (hexBuffer == nullptr) { + return "{}"; + } + int32_t ret = Crypto::ConvertBytesToHexString(hexBuffer, hexLen, blob.data, blob.size); + if (ret != DM_OK) { + delete[] hexBuffer; + return "{}"; + } + jsonArrayObj.PushBack(std::string(hexBuffer)); + delete[] hexBuffer; + } + jsonObject.Insert(TAG_CERT, jsonArrayObj); + return jsonObject.Dump(); +} + +bool ValidateInputJson(const std::string &data) +{ + JsonObject jsonObject; + jsonObject.Parse(data); + if (!IsUint32(jsonObject, TAG_CERT_COUNT) || !jsonObject.Contains(TAG_CERT)) { + LOGE("Missing required fields 'certCount' or 'cert'"); + return false; + } + const uint32_t certCount = jsonObject[TAG_CERT_COUNT].Get(); + if (certCount == 0 || certCount > MAX_CERT_COUNT) { + LOGE("Invalid certCount value %{public}u", certCount); + return false; + } + return true; +} + + bool ProcessCertItem(const JsonItemObject &item, DmBlob &cert, uint32_t processedIndex) + { + std::string hexStr = item.Get(); + const size_t hexLen = hexStr.length(); + if (hexLen == 0 || hexLen % HEX_TO_UINT8 != 0) { + LOGE("Invalid HEX length %{public}zu at index %{public}u", hexLen, processedIndex); + return false; + } + const uint32_t binSize = hexLen / HEX_TO_UINT8; + cert.data = new uint8_t[binSize]; + if (cert.data == nullptr) { + LOGE("Data allocation failed at index %{public}u", processedIndex); + return false; + } + int32_t ret = Crypto::ConvertHexStringToBytes(cert.data, binSize, hexStr.c_str(), hexLen); + if (ret != DM_OK) { + LOGE("HEX conversion failed at index %{public}u, ret = %{public}d", + processedIndex, ret); + delete[] cert.data; + cert.data = nullptr; + return false; + } + cert.size = binSize; + return true; +} + +bool AuthAttestCommon::DeserializeDmCertChain(const std::string &data, DmCertChain *outChain) +{ + if (outChain == nullptr || data.empty() || !ValidateInputJson(data)) { + LOGE("Invalid input"); + return false; + } + JsonObject jsonObject; + jsonObject.Parse(data); + const uint32_t certCount = jsonObject[TAG_CERT_COUNT].Get(); + JsonObject jsonArrayObj(JsonCreateType::JSON_CREATE_TYPE_ARRAY); + jsonArrayObj.Parse(jsonObject[TAG_CERT].Dump()); + DmBlob *certs = new DmBlob[certCount]{0}; + if (certs == nullptr) { + LOGE("Memory allocation failed for certs array"); + return false; + } + bool success = true; + uint32_t processedIndex = 0; + for (const auto &item : jsonArrayObj.Items()) { + if (!ProcessCertItem(item, certs[processedIndex], processedIndex)) { + success = false; + break; + } + processedIndex++; + } + if (!success) { + for (uint32_t i = 0; i < processedIndex; ++i) { + delete[] certs[i].data; + } + delete[] certs; + return false; + } + if (outChain->cert != nullptr) { + for (uint32_t i = 0; i < outChain->certCount; ++i) { + delete[] outChain->cert[i].data; + } + delete[] outChain->cert; + } + outChain->cert = certs; + outChain->certCount = certCount; + return true; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/attest/dm_auth_generate_attest.cpp b/services/implementation/src/attest/dm_auth_generate_attest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e62307472dcf9015d765ed0535b78f33d546076c --- /dev/null +++ b/services/implementation/src/attest/dm_auth_generate_attest.cpp @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2025 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 "dm_auth_generate_attest.h" + +#include "dm_error_type.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +constexpr uint64_t MIN_DCM_RANDOM = 0; +constexpr uint64_t MAX_DCM_RANDOM = 9999999999; + +int32_t AuthGenerateAttest::GenerateCertificate(DmCertChain &dmCertChain) +{ + LOGI("GenerateCertificate Start"); + DcmIdType ids[] = { DCM_ID_TYPE_UDID }; + uint64_t randomNum = GenRandLongLong(MIN_DCM_RANDOM, MAX_DCM_RANDOM); + DcmBlob challengeBlob = {sizeof(randomNum), (uint8_t *) &randomNum}; + DcmCertChain *dcmCertChain = new DcmCertChain(); + if (dcmCertChain == nullptr) { + LOGE("new dcmCertChain fail!"); + return ERR_DM_MALLOC_FAILED; + } + InitCertChain(dcmCertChain); + int32_t ret = DcmAttestIdsEx(ids, sizeof(ids)/sizeof(ids[0]), &challengeBlob, DCM_CERT_TYPE_ROOT_V2, dcmCertChain); + if (ret != DCM_SUCCESS) { + LOGE("DcmAttestIdsEx fail, ret=%{public}d", ret); + FreeCertChain(dcmCertChain); + return ret; + } + ret = ConvertDcmCertChainToDmCertChain(*dcmCertChain, dmCertChain); + if (ret != DM_OK) { + LOGE("covertToSoftbusCertChain fail. ret=%{public}d", ret); + FreeCertChain(dcmCertChain); + return ret; + } + FreeCertChain(dcmCertChain); + return DM_OK; +} + +int32_t AuthGenerateAttest::InitCertChain(DcmCertChain *certChain) +{ + if (certChain == nullptr) { + LOGE("certChain is nullptr."); + return ERR_DM_INPUT_PARA_INVALID; + } + LOGI("InitCertChain Start"); + certChain->certCount = DM_CERTS_COUNT; + certChain->cert = new DcmBlob[certChain->certCount]; + if (certChain->cert == nullptr) { + certChain->certCount = 0; + LOGE("new dcmCertChain.cert fail!"); + return ERR_DM_MALLOC_FAILED; + } + for (uint32_t i = 0; i < certChain->certCount; ++i) { + certChain->cert[i].data = new uint8_t[DM_CERTIFICATE_SIZE]{0}; + if (certChain->cert[i].data == nullptr) { + certChain->cert[i].size = 0; + for (uint32_t j = 0; j < i; ++j) { + delete[] certChain->cert[j].data; + certChain->cert[j].data = nullptr; + certChain->cert[j].size = 0; + } + delete[] certChain->cert; + certChain->cert = nullptr; + certChain->certCount = 0; + LOGE("new dcmCertChain.cert.data fail!"); + return ERR_DM_MALLOC_FAILED; + } + certChain->cert[i].size = DM_CERTIFICATE_SIZE; + } + return DM_OK; +} + +void AuthGenerateAttest::FreeCertChain(DcmCertChain *chain) +{ + if (chain == nullptr) { + LOGI("chain is nullptr!"); + return; + } + for (uint32_t i = 0; i < chain->certCount; ++i) { + delete[] chain->cert[i].data; + chain->cert[i].data = nullptr; + chain->cert[i].size = 0; + } + delete[] chain->cert; + chain->cert = nullptr; + chain->certCount = 0; + delete chain; +} + +int32_t ValidateInput(DcmCertChain &dcmCertChain) +{ + if (dcmCertChain.certCount > 0 && dcmCertChain.cert == nullptr) { + LOGE("Invalid cert chain: certCount>0 but cert array is null!"); + return ERR_DM_INPUT_PARA_INVALID; + } + return DM_OK; +} + +int32_t CopyCertificates(DcmCertChain &dcmCertChain, DmBlob *newCertArray, uint32_t &allocatedCerts) +{ + if (newCertArray == nullptr || newCertArray->length != dcmCertChain.certCount) { + LOGE("newCertArray is invalid param."); + return ERR_DM_INPUT_PARA_INVALID; + } + for (uint32_t i = 0; i < dcmCertChain.certCount; ++i) { + const auto &src = dcmCertChain.cert[i]; + auto &dest = newCertArray[i]; + dest.size = src.size; + dest.data = nullptr; + if (src.size == 0 || src.data == nullptr) continue; + dest.data = new uint8_t[src.size]{0}; + if (dest.data == nullptr) { + allocatedCerts = i; + return ERR_DM_MALLOC_FAILED; + } + + if (memcpy_s(dest.data, src.size, src.data, src.size) != DM_OK) { + delete[] dest.data; + dest.data = nullptr; + allocatedCerts = i; + return ERR_DM_FAILED; + } + allocatedCerts = i + 1; + } + return DM_OK; +} + +int32_t AuthGenerateAttest::ConvertDcmCertChainToDmCertChain(DcmCertChain &dcmCertChain, DmCertChain &dmCertChain) +{ + LOGI("ConvertDcmCertChainToDmCertChain start!"); + int32_t ret = ValidateInput(dcmCertChain); + if (ret != DM_OK) { + return ret; + } + if (dcmCertChain.certCount == 0) { + dmCertChain.cert = nullptr; + dmCertChain.certCount = 0; + return DM_OK; + } + DmBlob *newCertArray = new DmBlob[dcmCertChain.certCount]; + if (newCertArray == nullptr) { + LOGE("Failed to allocate cert array!"); + return ERR_DM_MALLOC_FAILED; + } + uint32_t allocatedCerts = 0; + ret = CopyCertificates(dcmCertChain, newCertArray, allocatedCerts); + if (ret != DM_OK) { + for (uint32_t j = 0; j < allocatedCerts; ++j) { + delete[] newCertArray[j].data; + } + delete[] newCertArray; + return ret; + } + dmCertChain.cert = newCertArray; + dmCertChain.certCount = dcmCertChain.certCount; + return DM_OK; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/attest/dm_auth_validate_attest.cpp b/services/implementation/src/attest/dm_auth_validate_attest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7b727b1ca6b40e5ec2a0660f56bd9636748e9542 --- /dev/null +++ b/services/implementation/src/attest/dm_auth_validate_attest.cpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2025 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 "dm_auth_validate_attest.h" + +#include "dm_error_type.h" +#include "dm_log.h" + +namespace OHOS { +namespace DistributedHardware { + +int32_t ProcessValidationResult(const char *deviceIdHash, char *udidStr, uint64_t randNum, HksParamSet *outputParam) +{ + if (deviceIdHash == nullptr || udidStr == nullptr || outputParam == nullptr) { + LOGE("input param is nullptr."); + return ERR_DM_INPUT_PARA_INVALID; + } + uint32_t cnt = 0; + HksBlob *blob = &outputParam->params[cnt].blob; + if (memcpy_s(&randNum, sizeof(uint64_t), blob->data, blob->size) != EOK) { + LOGE("memcpy randNum failed"); + return ERR_DM_GET_PARAM_FAILED; + } + blob = &outputParam->params[++cnt].blob; + if (memcpy_s(udidStr, UDID_BUF_LEN, blob->data, blob->size) != EOK) { + LOGE("memcpy udidStr failed"); + return ERR_DM_GET_PARAM_FAILED; + } + std::string certDeviceIdHash = Crypto::GetUdidHash(std::string(udidStr)); + if (strcmp(deviceIdHash, certDeviceIdHash.c_str()) != 0) { + LOGE("verifyCertificate fail"); + return ERR_DM_DESERIAL_CERT_FAILED; + } + return DM_OK; +} + +int32_t AuthValidateAttest::VerifyCertificate(DmCertChain &dmCertChain, const char *deviceIdHash) +{ + if (deviceIdHash == nullptr) { + LOGE("deviceIdHash is nullptr."); + return ERR_DM_INPUT_PARA_INVALID; + } + LOGI("VerifyCertificate start!"); + char udidStr[UDID_BUF_LEN] = {0}; + uint64_t randNum = 0; + HksCertChain hksCertChain; + int32_t ret = ConvertDmCertChainToHksCertChain(dmCertChain, hksCertChain); + if (ret != DM_OK) { + LOGE("ConvertDmCertChainToHksCertChain fail, ret=%{public}d", ret); + return ret; + } + HksParamSet *outputParam = NULL; + HksParam outputData[] = { + {.tag = HKS_TAG_ATTESTATION_CHALLENGE, .blob = {sizeof(uint64_t), (uint8_t *) &randNum}}, + {.tag = HKS_TAG_ATTESTATION_ID_UDID, .blob = {UDID_BUF_LEN, (uint8_t *)udidStr}}, + }; + ret = FillHksParamSet(&outputParam, outputData, sizeof(outputData) / sizeof(outputData[0])); + if (ret != DM_OK) { + LOGE("FillHksParamSet failed, ret=%{public}d", ret); + FreeHksCertChain(hksCertChain); + return ERR_DM_FAILED; + } + ret = HksValidateCertChain(&hksCertChain, outputParam); + if (ret != HKS_SUCCESS) { + LOGE("HksValidateCertChain fail, ret=%{public}d", ret); + FreeHksCertChain(hksCertChain); + return ret; + } + ret = ProcessValidationResult(deviceIdHash, udidStr, randNum, outputParam); + if (ret != DM_OK) { + LOGE("ProcessValidationResult fail, ret=%{public}d", ret); + FreeHksCertChain(hksCertChain); + return ret; + } + FreeHksCertChain(hksCertChain); + return DM_OK; +} + +int32_t AuthValidateAttest::FillHksParamSet(HksParamSet **paramSet, HksParam *param, int32_t paramNums) +{ + if (param == nullptr) { + LOGE("param is null"); + return ERR_DM_INPUT_PARA_INVALID; + } + int32_t ret = HksInitParamSet(paramSet); + if (ret != HKS_SUCCESS) { + LOGE("HksInitParamSet failed, hks ret = %{public}d", ret); + return ERR_DM_FAILED; + } + ret = HksAddParams(*paramSet, param, paramNums); + if (ret != HKS_SUCCESS) { + LOGE("HksAddParams failed, hks ret = %{public}d", ret); + HksFreeParamSet(paramSet); + return ERR_DM_FAILED; + } + ret = HksBuildParamSet(paramSet); + if (ret != HKS_SUCCESS) { + LOGE("HksBuildParamSet failed, hks ret = %{public}d", ret); + HksFreeParamSet(paramSet); + return ERR_DM_FAILED; + } + return DM_OK; +} + +void AuthValidateAttest::FreeHksCertChain(HksCertChain &chain) +{ + if (chain.certs != nullptr) { + for (uint32_t i = 0; i < chain.certsCount; ++i) { + chain.certs[i].size = 0; + delete[] chain.certs[i].data; + chain.certs[i].data = nullptr; + } + delete[] chain.certs; + chain.certs = nullptr; + } + chain.certsCount = 0; +} + +int32_t AllocateHksBlobArray(uint32_t count, HksBlob **outArray) +{ + HksBlob *arr = new HksBlob[count]{0}; + if (arr == nullptr) { + LOGE("Alloc failed for certs"); + return ERR_DM_MALLOC_FAILED; + } + *outArray = arr; + return DM_OK; +} + +int32_t CopySingleCert(const DmBlob &src, HksBlob &dest) +{ + if (src.data == nullptr || src.size == 0) { + LOGE("Invalid src cert"); + return ERR_DM_FAILED; + } + dest.data = new uint8_t[src.size]{0}; + if (dest.data == nullptr) { + LOGE("Alloc failed for size"); + return ERR_DM_MALLOC_FAILED; + } + dest.size = src.size; + if (memcpy_s(dest.data, src.size, src.data, src.size) != 0) { + LOGE("memcpy_s failed size"); + delete[] dest.data; + dest.data = nullptr; + return ERR_DM_FAILED; + } + return DM_OK; +} + +int32_t AuthValidateAttest::ConvertDmCertChainToHksCertChain(DmCertChain &dmCertChain, HksCertChain &hksCertChain) +{ + if (dmCertChain.certCount == 0 || dmCertChain.cert == nullptr) { + return ERR_DM_INPUT_PARA_INVALID; + } + HksBlob *newCerts = nullptr; + int32_t ret = AllocateHksBlobArray(dmCertChain.certCount, &newCerts); + if (ret != DM_OK) { + LOGE("AllocateHksBlobArray fail, ret = %{public}d", ret); + return ret; + } + for (uint32_t i = 0; i < dmCertChain.certCount; ++i) { + if ((ret = CopySingleCert(dmCertChain.cert[i], newCerts[i])) != DM_OK) { + FreeHksCertChain(hksCertChain); + delete[] newCerts; + return ret; + } + } + hksCertChain.certs = newCerts; + hksCertChain.certsCount = dmCertChain.certCount; + return DM_OK; +} +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/services/implementation/src/authentication_v2/auth_manager.cpp b/services/implementation/src/authentication_v2/auth_manager.cpp index 97f29240d6040ed719920d5d3d70a9cfd518f349..21d9563fadf4c78c34059ddd827b3b2d8aaa1ca5 100644 --- a/services/implementation/src/authentication_v2/auth_manager.cpp +++ b/services/implementation/src/authentication_v2/auth_manager.cpp @@ -36,6 +36,10 @@ #include "dm_auth_context.h" #include "dm_auth_message_processor.h" #include "dm_auth_state.h" +#if !defined(DEVICE_MANAGER_COMMON_FLAG) +#include "dm_auth_generate_attest.h" +#include "dm_auth_validate_attest.h" +#endif namespace OHOS { namespace DistributedHardware { @@ -130,8 +134,8 @@ AuthManager::AuthManager(std::shared_ptr softbusConnector, context_->authenticationMap[AUTH_TYPE_PIN_ULTRASONIC] = nullptr; context_->authenticationMap[AUTH_TYPE_NFC] = nullptr; context_->authenticationMap[AUTH_TYPE_CRE] = nullptr; - context_->accesser.dmVersion = DM_VERSION_5_1_0; - context_->accessee.dmVersion = DM_VERSION_5_1_0; + context_->accesser.dmVersion = DM_VERSION_5_1_1; + context_->accessee.dmVersion = DM_VERSION_5_1_1; context_->timer = std::make_shared(); context_->authMessageProcessor = std::make_shared(); } @@ -619,6 +623,28 @@ int32_t AuthManager::AuthenticateDevice(const std::string &pkgName, int32_t auth return DM_OK; } +std::string GenerateCertificate(std::shared_ptr context_) +{ +#ifdef DEVICE_MANAGER_COMMON_FLAG + if (context_ == nullptr) { + LOGE("context_ is nullptr!"); + return ERR_DM_INPUT_PARA_INVALID; + } + context_->accesser.isCommonFlag = true; + LOGI("Blue device do not generate cert!"); + return ""; +#else + DmCertChain dmCertChain; + int32_t certRet = AuthGenerateAttest::GetInstance().GenerateCertificate(dmCertChain); + if (certRet != DM_OK) { + LOGE("generate cert fail, certRet = %{public}d", certRet); + return ""; + } + std::string cert = AuthAttestCommon::GetInstance().SerializeDmCertChain(&dmCertChain); + return cert; +#endif +} + int32_t AuthManager::BindTarget(const std::string &pkgName, const PeerTargetId &targetId, const std::map &bindParam, int sessionId, uint64_t logicalSessionId) { @@ -660,6 +686,7 @@ int32_t AuthManager::BindTarget(const std::string &pkgName, const PeerTargetId & return ERR_DM_INPUT_PARA_INVALID; } + context_->accesser.cert = GenerateCertificate(context_); context_->sessionId = sessionId; context_->logicalSessionId = logicalSessionId; context_->requestId = static_cast(logicalSessionId); diff --git a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp index 3da6b139d17c620b655466851c424e2d5c7f7bfa..1eb1df5d2a6d3f094ab1f5632887c1fdf72ca88a 100644 --- a/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp +++ b/services/implementation/src/authentication_v2/auth_stages/auth_negotiate.cpp @@ -40,6 +40,10 @@ #include "multiple_user_connector.h" #include "os_account_manager.h" #include "parameter.h" +#if !defined(DEVICE_MANAGER_COMMON_FLAG) +#include "dm_auth_generate_attest.h" +#include "dm_auth_validate_attest.h" +#endif using namespace OHOS::Security::AccessToken; @@ -178,10 +182,41 @@ int32_t AuthSinkNegotiateStateMachine::ProcRespNegotiate5_1_0(std::shared_ptr context) +{ +#ifdef DEVICE_MANAGER_COMMON_FLAG + LOGI("Blue device do not verify cert!"); + return DM_OK; +#else + if (!CompareVersion(context->accesser.dmVersion, DM_VERSION_5_1_0)) { + LOGI("cert verify is not supported"); + return DM_OK; + } + if (CompareVersion(context->accesser.dmVersion, DM_VERSION_5_1_0) + && context->accesser.isCommonFlag == true) { + LOGI("src is common device."); + // 不校验证书,设置对端设备安全等级为0 + return DM_OK; + } + DmCertChain dmCertChain{nullptr, 0}; + if (!AuthAttestCommon::GetInstance() + .DeserializeDmCertChain(context->accesser.cert, &dmCertChain)) { + LOGE("cert deserialize fail!"); + return ERR_DM_DESERIAL_CERT_FAILED; + } + int32_t certRet = AuthValidateAttest::GetInstance() + .VerifyCertificate(dmCertChain, context->accesser.deviceIdHash.c_str()); + if (certRet != DM_OK) { + LOGE("validate cert fail, certRet = %{public}d", certRet); + return ERR_DM_VERIFY_CERT_FAILED; + } + return DM_OK; +#endif +} + int32_t AuthSinkNegotiateStateMachine::Action(std::shared_ptr context) { LOGI("AuthSinkNegotiateStateMachine::Action sessionid %{public}d", context->sessionId); - // 1. Create an authorization timer if (context->timer != nullptr) { context->timer->StartTimer(std::string(AUTHENTICATE_TIMEOUT_TASK), @@ -190,7 +225,6 @@ int32_t AuthSinkNegotiateStateMachine::Action(std::shared_ptr con DmAuthState::HandleAuthenticateTimeout(context, name); }); } - // To be compatible with historical versions, use ConvertSrcVersion to get the actual version on the source side. std::string preVersion = std::string(DM_VERSION_5_0_OLD_MAX); LOGI("AuthSinkNegotiateStateMachine::Action start version compare %{public}s to %{public}s", @@ -200,8 +234,14 @@ int32_t AuthSinkNegotiateStateMachine::Action(std::shared_ptr con context->reason = ERR_DM_VERSION_INCOMPATIBLE; return ERR_DM_VERSION_INCOMPATIBLE; } - - int32_t ret = ProcRespNegotiate5_1_0(context); + // verify cert + int32_t ret = VerifyCertificate(context); + if (ret != DM_OK) { + LOGE("AuthSinkNegotiateStateMachine::Action cert verify fail!"); + context->reason = ret; + return ret; + } + ret = ProcRespNegotiate5_1_0(context); if (ret != DM_OK) { LOGE("AuthSinkNegotiateStateMachine::Action proc response negotiate failed"); context->reason = ret; diff --git a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp index dab0d68fba17f3edbc83577e5860d3c0397d06fd..f2d4fd466207eb05a16d562b45dae89683a78c78 100644 --- a/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_manager_base.cpp @@ -77,6 +77,10 @@ const char* GET_ULTRASONIC_PIN_TIMEOUT_TASK = "deviceManagerTimer:getUltrasonicP const char* ADD_TIMEOUT_TASK = "deviceManagerTimer:add"; const char* WAIT_SESSION_CLOSE_TIMEOUT_TASK = "deviceManagerTimer:waitSessionClose"; const char* CLOSE_SESSION_TASK_SEPARATOR = "#"; +const char* TAG_DM_CERT_CHAIN = "dmCertChain"; +const char* TAG_CERT_COUNT = "certCount"; +const char* TAG_CERT = "cert"; +const char* TAG_IS_COMMON_FLAG = "isCommonFlag"; const int32_t AUTHENTICATE_TIMEOUT = 120; const int32_t CONFIRM_TIMEOUT = 60; diff --git a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp index 38427822cfac8965e610baba0476133612bce07a..c9b3821abaa6bad61345c4f549f65b26d673fa88 100644 --- a/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp +++ b/services/implementation/src/authentication_v2/dm_auth_message_processor.cpp @@ -647,12 +647,15 @@ int32_t DmAuthMessageProcessor::CreateNegotiateMessage(std::shared_ptraccesser.tokenIdHash; jsonObject[TAG_BUNDLE_NAME_V2] = context->accesser.bundleName; jsonObject[TAG_EXTRA_INFO] = context->accesser.extraInfo; + jsonObject[TAG_IS_COMMON_FLAG] = context->accesser.isCommonFlag; + jsonObject[TAG_DM_CERT_CHAIN] = context->accesser.cert; jsonObject[TAG_PEER_BUNDLE_NAME_V2] = context->accessee.bundleName; jsonObject[TAG_ULTRASONIC_SIDE] = static_cast(context->ultrasonicInfo); jsonObject[TAG_PEER_DISPLAY_ID] = context->accessee.displayId; jsonObject[TAG_PEER_PKG_NAME] = context->accessee.pkgName; jsonObject[TAG_HOST_PKGLABEL] = context->pkgLabel; + return DM_OK; } @@ -974,17 +977,14 @@ int32_t DmAuthMessageProcessor::ParseNegotiateMessage( context->logicalSessionId = jsonObject[DM_TAG_LOGICAL_SESSION_ID].Get(); context->requestId = static_cast(context->logicalSessionId); } - if (jsonObject[TAG_PKG_NAME].IsString()) { context->pkgName = jsonObject[TAG_PKG_NAME].Get(); context->accesser.pkgName = context->pkgName; context->accessee.pkgName = context->accesser.pkgName; } - if (jsonObject[TAG_PEER_PKG_NAME].IsString()) { context->accessee.pkgName = jsonObject[TAG_PEER_PKG_NAME].Get(); } - if (jsonObject[TAG_DM_VERSION_V2].IsString()) { context->accesser.dmVersion = jsonObject[TAG_DM_VERSION_V2].Get(); } @@ -1003,7 +1003,6 @@ int32_t DmAuthMessageProcessor::ParseNegotiateMessage( if (jsonObject[TAG_BUNDLE_NAME_V2].IsString()) { context->accesser.bundleName = jsonObject[TAG_BUNDLE_NAME_V2].Get(); } - if (jsonObject[TAG_EXTRA_INFO].IsString()) { context->accesser.extraInfo = jsonObject[TAG_EXTRA_INFO].Get(); } @@ -1018,11 +1017,22 @@ int32_t DmAuthMessageProcessor::ParseNegotiateMessage( context->pkgLabel = jsonObject[TAG_HOST_PKGLABEL].Get(); } ParseUltrasonicSide(jsonObject, context); - + ParseCert(jsonObject, context); context->authStateMachine->TransitionTo(std::make_shared()); return DM_OK; } +void DmAuthMessageProcessor::ParseCert(const JsonObject &jsonObject, + std::shared_ptr context) +{ + if (jsonObject[TAG_DM_CERT_CHAIN].IsString()) { + context->accesser.cert = jsonObject[TAG_DM_CERT_CHAIN].Get(); + } + if (jsonObject[TAG_IS_COMMON_FLAG].IsBoolean()) { + context->accesser.isCommonFlag = jsonObject[TAG_IS_COMMON_FLAG].Get(); + } +} + void DmAuthMessageProcessor::ParseUltrasonicSide( const JsonObject &jsonObject, std::shared_ptr context) { diff --git a/test/commonfuzztest/authenticatedeviceserviceimpl_fuzzer/BUILD.gn b/test/commonfuzztest/authenticatedeviceserviceimpl_fuzzer/BUILD.gn index 6a4dccbc02a5bdffe3dcd3c630eb179facc98ca9..f79c6dfe0658f1a481bd1cf8d88ce64fa6f10ba6 100644 --- a/test/commonfuzztest/authenticatedeviceserviceimpl_fuzzer/BUILD.gn +++ b/test/commonfuzztest/authenticatedeviceserviceimpl_fuzzer/BUILD.gn @@ -85,6 +85,13 @@ ohos_fuzztest("AuthenticateDeviceServiceImplFuzzTest") { "safwk:system_ability_fwk", "selinux_adapter:librestorecon", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ############################################################################### diff --git a/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn b/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn index fb2de39cab0aa6a70aefea49cc690e3e5d00b8f4..93e9b15d99aff4c62f07e483c8c23d23fa946382 100644 --- a/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn +++ b/test/commonfuzztest/dmauthmanagerv2_fuzzer/BUILD.gn @@ -69,6 +69,13 @@ ohos_fuzztest("DmAuthManagerV2FuzzTest") { "DH_LOG_TAG=\"DmAuthManagerV2FuzzTest\"", "LOG_DOMAIN=0xD004110", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ############################################################################### diff --git a/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn b/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn index b81e1b47298dfc17c2d5288fd1d947d192304f19..c6f9f7df8f3cfe584626f2b55e434832151711b7 100644 --- a/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn +++ b/test/commonfuzztest/ondatareceivedv2_fuzzer/BUILD.gn @@ -68,6 +68,13 @@ ohos_fuzztest("OnDataReceivedV2FuzzTest") { "DH_LOG_TAG=\"OnDataReceivedV2FuzzTest\"", "LOG_DOMAIN=0xD004110", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ############################################################################### diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index f0af8d78f5bd582c7e922368ee98b3acc709e454..a82f0cd598efe4687ff7d9d89ba9c164a0388bb5 100644 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -400,6 +400,13 @@ ohos_unittest("UTTest_device_manager_service") { "hilog:libhilog", "selinux_adapter:librestorecon", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_device_manager_service }}} @@ -427,6 +434,13 @@ ohos_unittest("UTTest_dm_softbus_cache") { "hilog:libhilog", "selinux_adapter:librestorecon", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_dm_softbus_cache }}} @@ -460,6 +474,13 @@ ohos_unittest("UTTest_device_manager_service_three") { "hilog:libhilog", "selinux_adapter:librestorecon", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_device_manager_service_three }}} @@ -1250,6 +1271,13 @@ ohos_unittest("UTTest_device_manager_service_impl") { "os_account:libaccountkits", "os_account:os_account_innerkits", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_device_manager_service_impl }}} @@ -1280,6 +1308,13 @@ ohos_unittest("UTTest_device_manager_service_impl_first") { "os_account:libaccountkits", "os_account:os_account_innerkits", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_device_manager_service_impl_first }}} @@ -2037,6 +2072,13 @@ ohos_unittest("UTTest_auth_pin_auth_state") { "googletest:gmock_main", "hilog:libhilog", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_auth_pin_auth_state }}} @@ -2095,6 +2137,13 @@ ohos_unittest("UTTest_auth_credential_state") { "googletest:gmock_main", "hilog:libhilog", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_auth_credential_state }}} @@ -2126,6 +2175,13 @@ ohos_unittest("UTTest_auth_acl") { "googletest:gmock_main", "hilog:libhilog", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_auth_acl }}} @@ -2159,6 +2215,13 @@ ohos_unittest("UTTest_auth_negotiate") { "googletest:gmock_main", "hilog:libhilog", ] + + if (!device_manager_common) { + external_deps += [ + "device_certificate_manager:device_cert_mgr_sdk", + "huks:libhukssdk", + ] + } } ## UnitTest UTTest_auth_negotiate }}}