diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e8bad4364fd22518905daeea04f61dc8a801613c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.vscode/ +.clang-format + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..29f81d812f3e768fa89638d1f72920dbfd1413a8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/README.md b/README.md index 46da93406a331c8ff84ff4963cda46a4e7d4a1a6..88c9af1fc9f5690e095d43c845458bb9039d396f 100644 --- a/README.md +++ b/README.md @@ -36,4 +36,4 @@ Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/baselib/msglib/BUILD.gn b/baselib/msglib/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..dcd892d9abf16ca922723a64af76fbc4ab238fb8 --- /dev/null +++ b/baselib/msglib/BUILD.gn @@ -0,0 +1,53 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# messenger_static lib +config("messenger_static_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +ohos_static_library("messenger_static") { + include_dirs = [ + "include", + "src", + ] + + sources = [ "src/messenger.c" ] + + if (is_standard_system) { + include_dirs += [ "src/standard" ] + sources += [ + "src/standard/messenger_device_session_manager.c", + "src/standard/messenger_device_status_manager.c", + "src/standard/messenger_impl.c", + ] + external_deps = [ + "dsoftbus_standard:softbus_client", + "hilog_native:libhilog", + "utils_base:utils", + ] + } + + if (is_large_system) { + include_dirs += [ "src/large" ] + } + + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + + public_configs = [ ":messenger_static_config" ] + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/baselib/msglib/include/messenger.h b/baselib/msglib/include/messenger.h new file mode 100644 index 0000000000000000000000000000000000000000..9605670289606422655362f6d7cd0a5d8cf00d4a --- /dev/null +++ b/baselib/msglib/include/messenger.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2021 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 SEC_MESSENGER_INFO_H +#define SEC_MESSENGER_INFO_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef DEVICE_SECURITY_DEFINES_H +#define DEVICE_ID_MAX_LEN 64 +typedef struct DeviceIdentify { + uint32_t length; + uint8_t identity[DEVICE_ID_MAX_LEN]; +} DeviceIdentify; +#endif + +typedef int32_t (*DeviceMessageReceiver)(const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen); + +typedef int32_t (*DeviceStatusReceiver)(const DeviceIdentify *devId, uint32_t status, uint32_t devType); + +typedef int32_t (*MessageSendResultNotifier)(const DeviceIdentify *devId, uint64_t transNo, uint32_t result); + +typedef int32_t (*DeviceProcessor)(const DeviceIdentify *devId, uint32_t devType, void *para); + +typedef struct MessengerConfig { + const char *pkgName; + const char *sessName; + DeviceMessageReceiver messageReceiver; + DeviceStatusReceiver statusReceiver; + MessageSendResultNotifier sendResultNotifier; + uint32_t threadCnt; +} MessengerConfig; + +typedef struct StatisticInformation { + uint64_t firstOnlineTime; + uint64_t lastOnlineTime; + uint64_t firstOfflineTime; + uint64_t lastOfflineTime; + uint64_t lastSessOpenTime; + uint32_t lastSessOpenResult; + uint32_t lastSessOpenCost; + uint64_t lastSessCloseTime; + uint64_t lastMsgSendTime; + uint32_t lastMsgSendResult; + uint32_t lastMsgSendCost; + uint64_t lastMsgRecvTime; + uint64_t packetRx; + uint64_t packetTotalRx; + uint64_t packetTx; + uint64_t packetTotalTx; + uint64_t packetTxFailed; + uint64_t packetTotalTxFailed; +} StatisticInformation; + +typedef struct Messenger Messenger; + +Messenger *CreateMessenger(const MessengerConfig *config); + +void DestroyMessenger(Messenger *messenger); + +bool IsMessengerReady(const Messenger *messenger); + +void SendMsgTo(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, + uint32_t msgLen); + +bool GetDeviceOnlineStatus(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType); + +bool GetSelfDeviceIdentify(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType); + +void ForEachDeviceProcess(const Messenger *messenger, const DeviceProcessor processor, void *para); + +bool GetDeviceStatisticInfo(const Messenger *messenger, const DeviceIdentify *devId, StatisticInformation *info); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_MESSENGER_INFO_H diff --git a/baselib/msglib/src/messenger.c b/baselib/msglib/src/messenger.c new file mode 100644 index 0000000000000000000000000000000000000000..1a4ff21e709d730e10ec356f32747c53f2816ccc --- /dev/null +++ b/baselib/msglib/src/messenger.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2021 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 "messenger.h" +#include "messenger_impl.h" + +Messenger *CreateMessenger(const MessengerConfig *config) +{ + return CreateMessengerImpl(config); +} + +void DestroyMessenger(Messenger *messenger) +{ + DestroyMessengerImpl(messenger); +} + +bool IsMessengerReady(const Messenger *messenger) +{ + return IsMessengerReadyImpl(messenger); +} + +void SendMsgTo(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, + uint32_t msgLen) +{ + SendMsgToImpl(messenger, transNo, devId, msg, msgLen); +} + +bool GetDeviceOnlineStatus(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType) +{ + return GetDeviceOnlineStatusImpl(messenger, devId, devType); +} + +bool GetSelfDeviceIdentify(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) +{ + return GetSelfDeviceIdentifyImpl(messenger, devId, devType); +} + +void ForEachDeviceProcess(const Messenger *messenger, const DeviceProcessor processor, void *para) +{ + ForEachDeviceProcessImpl(messenger, processor, para); +} + +bool GetDeviceStatisticInfo(const Messenger *messenger, const DeviceIdentify *devId, StatisticInformation *info) +{ + return GetDeviceStatisticInfoImpl(messenger, devId, info); +} \ No newline at end of file diff --git a/baselib/msglib/src/messenger_impl.h b/baselib/msglib/src/messenger_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..c79709bb82916981e28ce1847afe7fd42f0da0f2 --- /dev/null +++ b/baselib/msglib/src/messenger_impl.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2021 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 SEC_MESSENGER_IMPL_H +#define SEC_MESSENGER_IMPL_H + +#include "messenger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +Messenger *CreateMessengerImpl(const MessengerConfig *config) __attribute__((weak)); + +void DestroyMessengerImpl(Messenger *messenger) __attribute__((weak)); + +void SendMsgToImpl(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, + uint32_t msgLen) __attribute__((weak)); + +bool IsMessengerReadyImpl(const Messenger *messenger) __attribute__((weak)); + +bool GetDeviceOnlineStatusImpl(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType) + __attribute__((weak)); + +bool GetSelfDeviceIdentifyImpl(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) + __attribute__((weak)); + +void ForEachDeviceProcessImpl(const Messenger *messenger, const DeviceProcessor processor, void *para) + __attribute__((weak)); + +bool GetDeviceStatisticInfoImpl(const Messenger *messenger, const DeviceIdentify *devId, StatisticInformation *info) + __attribute__((weak)); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_MESSENGER_IMPL_H diff --git a/baselib/msglib/src/standard/messenger_device_session_manager.c b/baselib/msglib/src/standard/messenger_device_session_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..c7da0818a11cc1f11cc4a48f59e937c7431f8f89 --- /dev/null +++ b/baselib/msglib/src/standard/messenger_device_session_manager.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2021 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 "securec.h" +#include "session.h" + +#include "utils_list.h" +#include "utils_log.h" +#include "utils_mem.h" +#include "utils_mutex.h" + +#include "messenger_device_session_manager.h" +#include "messenger_device_status_manager.h" +#include "messenger_utils.h" + +#define IS_SERVER 0 + +static int MessengerOnSessionOpened(int sessionId, int result); +static void MessengerOnSessionClosed(int sessionId); +static void MessengerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen); +static void MessengerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen); + +typedef struct DeviceSessionManager { + const ISessionListener listener; + ListHead pendingSendList; + ListHead opendSessionList; + DeviceMessageReceiver messageReceiver; + MessageSendResultNotifier sendResultNotifier; + const char *pkgName; + const char *sessionName; + WorkQueue *queue; + Mutex mutex; +} DeviceSessionManager; + +typedef struct QueueMsgData { + DeviceIdentify srcIdentity; + uint32_t msgLen; + uint8_t msgdata[1]; +} QueueMsgData; + +typedef struct PendingMsgData { + ListNode link; + uint32_t transNo; + DeviceIdentify destIdentity; + uint32_t msgLen; + uint8_t msgdata[1]; +} PendingMsgData; + +typedef struct SessionInfo { + ListNode link; + int32_t sessionId; + DeviceIdentify identity; +} SessionInfo; + +static inline DeviceSessionManager *GetDeviceSessionManagerInstance() +{ + static DeviceSessionManager manager = { + { + .OnSessionOpened = MessengerOnSessionOpened, + .OnSessionClosed = MessengerOnSessionClosed, + .OnBytesReceived = MessengerOnBytesReceived, + .OnMessageReceived = MessengerOnMessageReceived, + }, + .pendingSendList = INIT_LIST(manager.pendingSendList), + .opendSessionList = INIT_LIST(manager.opendSessionList), + .messageReceiver = NULL, + .sendResultNotifier = NULL, + .queue = NULL, + .mutex = INITED_MUTEX, + }; + return &manager; +} + +static void ProcessSessionMessageReceived(const uint8_t *data, uint32_t len) +{ + if (data == NULL || len == 0) { + return; + } + QueueMsgData *queueData = (QueueMsgData *)data; + if (queueData->msgLen + sizeof(QueueMsgData) != len) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, invalid input"); + return; + } + + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + DeviceMessageReceiver messageReceiver = instance->messageReceiver; + if (messageReceiver == NULL) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, messageReceiver is null"); + return; + } + messageReceiver(&queueData->srcIdentity, queueData->msgdata, queueData->msgLen); + FREE(queueData); +} + +static inline void OnSessionMessageReceived(const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) +{ + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + WorkQueue *queue = instance->queue; + if (queue == NULL) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, queue is null"); + return; + } + DeviceMessageReceiver messageReceiver = instance->messageReceiver; + if (messageReceiver == NULL) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, messageReceiver is null"); + return; + } + uint32_t queueDataLen = sizeof(QueueMsgData) + msgLen; + QueueMsgData *queueData = MALLOC(queueDataLen); + if (queueData == NULL) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, malloc result null"); + return; + } + uint32_t ret = memcpy_s(&queueData->srcIdentity, sizeof(DeviceIdentify), devId, sizeof(DeviceIdentify)); + if (ret != EOK) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, memcpy failed"); + FREE(queueData); + return; + } + ret = memcpy_s(queueData->msgdata, msgLen, msg, msgLen); + if (ret != EOK) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, memcpy failed"); + FREE(queueData); + return; + } + queueData->msgLen = msgLen; + ret = QueueWork(queue, ProcessSessionMessageReceived, (uint8_t *)queueData, queueDataLen); + if (ret != WORK_QUEUE_OK) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, QueueWork failed, ret is %{public}u", ret); + FREE(queueData); + return; + } +} + +static bool GetDeviceIdentityFromSessionId(int sessionId, DeviceIdentify *identity, uint32_t *maskId) +{ + if (identity == NULL || maskId == NULL) { + return false; + } + char deviceName[DEVICE_ID_MAX_LEN + 1] = {0}; + int ret = GetPeerDeviceId(sessionId, deviceName, DEVICE_ID_MAX_LEN + 1); + if (ret != 0) { + SECURITY_LOG_INFO("GetDeviceIdentityFromSessionId %{public}d failed, result is %{public}d", sessionId, ret); + return false; + } + *maskId = MaskDeviceIdentity(deviceName, DEVICE_ID_MAX_LEN); + identity->length = DEVICE_ID_MAX_LEN; + memcpy_s(&identity->identity, DEVICE_ID_MAX_LEN, deviceName, DEVICE_ID_MAX_LEN); + return true; +} + +static int MessengerOnSessionOpened(int sessionId, int result) +{ + int side = GetSessionSide(sessionId); + DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}}; + uint32_t maskId; + bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId); + if (ret == false) { + SECURITY_LOG_ERROR("MessengerOnSessionOpened GetDeviceIdentityFromSessionId failed"); + return 0; + } + + SECURITY_LOG_INFO("MessengerOnSessionOpened device=%{public}x, ret=%{public}s, side=%{public}s", maskId, + (result == 0) ? "succ" : "failed", (side == IS_SERVER) ? "server" : "client"); + + if (side == IS_SERVER) { + return 0; + } + if (result != 0) { + return 0; + } + + SessionInfo *sessionInfo = MALLOC(sizeof(SessionInfo)); + if (sessionInfo == NULL) { + SECURITY_LOG_ERROR("MessengerOnSessionOpened malloc failed"); + return 0; + } + sessionInfo->sessionId = sessionId; + memcpy_s(&sessionInfo->identity, sizeof(DeviceIdentify), &identity, sizeof(DeviceIdentify)); + + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + LockMutex(&instance->mutex); + AddListNodeBefore(&sessionInfo->link, &instance->opendSessionList); + + ListNode *node = NULL; + ListNode *temp = NULL; + + FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) { + PendingMsgData *MsgData = LIST_ENTRY(node, PendingMsgData, link); + RemoveListNode(node); + int ret = SendMessage(sessionId, MsgData->msgdata, MsgData->msgLen); + if (ret != 0) { + SECURITY_LOG_ERROR("MessengerSendMsgTo SendMessage error code = %{publc}d", ret); + } + FREE(MsgData); + } + + UnlockMutex(&instance->mutex); + return 0; +} + +static void MessengerOnSessionClosed(int sessionId) +{ + int side = GetSessionSide(sessionId); + DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}}; + uint32_t maskId; + bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId); + if (ret == false) { + SECURITY_LOG_ERROR("MessengerOnSessionClosed GetDeviceIdentityFromSessionId failed"); + return; + } + + SECURITY_LOG_INFO("MessengerOnSessionClosed device=%{public}x, side=%{public}s", maskId, + (side == IS_SERVER) ? "server" : "client"); + + if (side == IS_SERVER) { + return; + } + + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + LockMutex(&instance->mutex); + ListNode *node = NULL; + ListNode *temp = NULL; + FOREACH_LIST_NODE_SAFE (node, &instance->opendSessionList, temp) { + SessionInfo *info = LIST_ENTRY(node, SessionInfo, link); + if (info->sessionId == sessionId) { + RemoveListNode(node); + FREE(info); + } + } + UnlockMutex(&instance->mutex); + return; +} + +static void MessengerOnBytesReceived(int sessionId, const void *data, unsigned int dataLen) +{ + DeviceIdentify identity = {DEVICE_ID_MAX_LEN, {0}}; + uint32_t maskId; + bool ret = GetDeviceIdentityFromSessionId(sessionId, &identity, &maskId); + if (ret == false) { + return; + } + SECURITY_LOG_INFO("MessengerOnBytesReceived from device(%{public}x***, data length is %{public}u", maskId, dataLen); + OnSessionMessageReceived(&identity, (const uint8_t *)data, (uint32_t)dataLen); +} + +static void MessengerOnMessageReceived(int sessionId, const void *data, unsigned int dataLen) +{ + return MessengerOnBytesReceived(sessionId, data, dataLen); +} + +bool InitDeviceSessionManager(WorkQueue *queue, const char *pkgName, const char *sessionName, + DeviceMessageReceiver messageReceiver, MessageSendResultNotifier sendResultNotifier) +{ + if ((pkgName == NULL) || (sessionName == NULL)) { + return false; + } + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + instance->pkgName = pkgName; + instance->sessionName = sessionName; + instance->messageReceiver = messageReceiver; + instance->sendResultNotifier = sendResultNotifier; + instance->queue = queue; + int try = 0; + int ret = CreateSessionServer(pkgName, sessionName, &instance->listener); + while (ret != 0 && try < MAX_TRY_TIMES) { + MessengerSleep(1); // sleep 1 second and try again + ret = CreateSessionServer(pkgName, sessionName, &instance->listener); + try++; + } + + if (ret != 0) { + SECURITY_LOG_ERROR("InitSessionManager CreateSessionServer failed = %{public}d", ret); + return false; + } + + SECURITY_LOG_INFO("InitSessionManager CreateSessionServer success"); + return true; +} + +bool DeInitDeviceSessionManager() +{ + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + int ret = RemoveSessionServer(instance->pkgName, instance->sessionName); + if (ret != 0) { + SECURITY_LOG_ERROR("DeInitSessionManager RemoveSessionServer failed = %{public}d", ret); + return false; + } + LockMutex(&instance->mutex); + instance->pkgName = NULL; + instance->sessionName = NULL; + instance->messageReceiver = NULL; + instance->sendResultNotifier = NULL; + instance->queue = NULL; + + ListNode *node = NULL; + ListNode *temp = NULL; + + FOREACH_LIST_NODE_SAFE (node, &instance->pendingSendList, temp) { + PendingMsgData *MsgData = LIST_ENTRY(node, PendingMsgData, link); + RemoveListNode(node); + FREE(MsgData); + } + + FOREACH_LIST_NODE_SAFE (node, &instance->opendSessionList, temp) { + SessionInfo *info = LIST_ENTRY(node, SessionInfo, link); + RemoveListNode(node); + FREE(info); + } + + DestroyWorkQueue(instance->queue); + UnlockMutex(&instance->mutex); + + SECURITY_LOG_INFO("DeInitSessionManager RemoveSessionServer success"); + return true; +} + +static bool GetOpenedSessionId(const DeviceIdentify *devId, int32_t *sessionId) +{ + if (devId == NULL || sessionId == NULL) { + return false; + } + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + + bool find = false; + LockMutex(&instance->mutex); + ListNode *node = NULL; + uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length); + + FOREACH_LIST_NODE (node, &instance->opendSessionList) { + SessionInfo *sessionInfo = LIST_ENTRY(node, SessionInfo, link); + if (IsSameDevice(&sessionInfo->identity, devId)) { + *sessionId = sessionInfo->sessionId; + find = true; + break; + } + } + UnlockMutex(&instance->mutex); + SECURITY_LOG_DEBUG("GetOpenedSessionId for device %{public}x %{public}s", mask, find ? "succ" : "failed"); + return find; +} + +static void PushMsgDataToPendingList(uint32_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) +{ + PendingMsgData *data = MALLOC(sizeof(PendingMsgData) + msgLen); + if (data == NULL) { + SECURITY_LOG_ERROR("PushMsgDataToPendingList malloc error"); + return; + } + data->transNo = transNo; + data->msgLen = msgLen; + memcpy_s(&data->destIdentity, sizeof(DeviceIdentify), devId, sizeof(DeviceIdentify)); + memcpy_s(data->msgdata, msgLen, msg, msgLen); + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + LockMutex(&instance->mutex); + AddListNodeBefore(&data->link, &instance->pendingSendList); + UnlockMutex(&instance->mutex); +} + +static void CreateNewDeviceSession(const DeviceIdentify *devId) +{ + uint32_t mask = MaskDeviceIdentity((const char *)&devId->identity[0], devId->length); + char deviceName[DEVICE_ID_MAX_LEN + 1] = {0}; + memcpy_s(deviceName, DEVICE_ID_MAX_LEN, devId->identity, DEVICE_ID_MAX_LEN); + + const SessionAttribute attr = { + .dataType = TYPE_MESSAGE, + }; + DeviceSessionManager *instance = GetDeviceSessionManagerInstance(); + int ret = OpenSession(instance->sessionName, instance->sessionName, deviceName, "", &attr); + if (ret != 0) { + ret = OpenSession(instance->sessionName, instance->sessionName, deviceName, "", &attr); + } + SECURITY_LOG_INFO("CreateNewDeviceSession for device %{public}x ret is %{public}d", mask, ret); + if (ret != 0) { + } +} + +void MessengerSendMsgTo(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) +{ + if (devId == NULL || msg == NULL || msgLen == 0) { + SECURITY_LOG_ERROR("MessengerSendMsgTo error for invalid para"); + return; + } + + static DeviceIdentify self = {0, {0}}; + uint32_t devType; + MessengerGetSelfDeviceIdentify(&self, &devType); + + if (IsSameDevice(&self, devId)) { + SECURITY_LOG_DEBUG("MessengerSendMsgTo loopback msg"); + OnSessionMessageReceived(devId, msg, msgLen); + return; + } + + int32_t sessionId; + bool find = GetOpenedSessionId(devId, &sessionId); + if (find) { + int ret = SendMessage(sessionId, msg, msgLen); + if (ret != 0) { + SECURITY_LOG_ERROR("MessengerSendMsgTo SendMessage error code = %{publc}d", ret); + } + } else { + PushMsgDataToPendingList(transNo, devId, msg, msgLen); + CreateNewDeviceSession(devId); + } +} \ No newline at end of file diff --git a/baselib/msglib/src/standard/messenger_device_session_manager.h b/baselib/msglib/src/standard/messenger_device_session_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..b8e5a754de59cef785debc293745b01024188dd2 --- /dev/null +++ b/baselib/msglib/src/standard/messenger_device_session_manager.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 SEC_MESSENGER_DEVICE_SESSION_MANAGER_H +#define SEC_MESSENGER_DEVICE_SESSION_MANAGER_H + +#include "messenger.h" + +#include "utils_work_queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool InitDeviceSessionManager(WorkQueue *queue, const char *pkgName, const char *sessionName, + DeviceMessageReceiver messageReceiver, MessageSendResultNotifier sendResultNotifier); + +bool DeInitDeviceSessionManager(); + +void MessengerSendMsgTo(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_MESSENGER_DEVICE_SESSION_MANAGER_H diff --git a/baselib/msglib/src/standard/messenger_device_status_manager.c b/baselib/msglib/src/standard/messenger_device_status_manager.c new file mode 100644 index 0000000000000000000000000000000000000000..8137d522b71ccbaa84ab34d1f6c982a058df8e6c --- /dev/null +++ b/baselib/msglib/src/standard/messenger_device_status_manager.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 2021 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 "messenger_device_status_manager.h" + +#include + +#include "securec.h" +#include "softbus_bus_center.h" +#include "utils_log.h" +#include "utils_mem.h" + +#include "messenger_utils.h" +static void MessengerOnNodeOnline(NodeBasicInfo *info); +static void MessengerOnNodeOffline(NodeBasicInfo *info); +static void MessengerOnNodeBasicInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info); + +typedef struct DeviceStatusManager { + const INodeStateCb nodeStateCb; + DeviceStatusReceiver deviceStatusReceiver; + const char *pkgName; + WorkQueue *queue; +} DeviceStatusManager; + +typedef struct QueueStatusData { + DeviceIdentify srcIdentity; + uint32_t status; + uint32_t devType; +} QueueStatusData; + +static inline DeviceStatusManager *GetDeviceManagerInstance() +{ + static DeviceStatusManager manager = { + { + .events = EVENT_NODE_STATE_ONLINE | EVENT_NODE_STATE_OFFLINE, + .onNodeOnline = MessengerOnNodeOnline, + .onNodeOffline = MessengerOnNodeOffline, + .onNodeBasicInfoChanged = MessengerOnNodeBasicInfoChanged, + }, + .deviceStatusReceiver = NULL, + .pkgName = NULL, + .queue = NULL, + }; + return &manager; +} + +static void ProcessDeviceStatusReceived(const uint8_t *data, uint32_t len) +{ + if (data == NULL || len == 0) { + return; + } + QueueStatusData *queueData = (QueueStatusData *)data; + if (sizeof(QueueStatusData) != len) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceived, invalid input"); + return; + } + + DeviceStatusManager *instance = GetDeviceManagerInstance(); + DeviceStatusReceiver deviceStatusReceiver = instance->deviceStatusReceiver; + if (deviceStatusReceiver == NULL) { + SECURITY_LOG_ERROR("ProcessSessionMessageReceived, messageReceiver is null"); + return; + } + deviceStatusReceiver(&queueData->srcIdentity, queueData->status, queueData->devType); + FREE(queueData); +} + +static inline void ProcessDeviceStatusReceiver(const DeviceIdentify *devId, uint32_t status, uint32_t devType) +{ + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + WorkQueue *queue = instance->queue; + if (queue == NULL) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, queue is null"); + return; + } + + DeviceStatusReceiver deviceStatusReceiver = instance->deviceStatusReceiver; + if (deviceStatusReceiver == NULL) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, messageReceiver is null"); + return; + } + + QueueStatusData *data = MALLOC(sizeof(QueueStatusData)); + if (data == NULL) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, malloc result null"); + return; + } + + uint32_t ret = memcpy_s(&data->srcIdentity, sizeof(DeviceIdentify), devId, sizeof(DeviceIdentify)); + if (ret != EOK) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, memcpy failed"); + FREE(data); + return; + } + data->devType = devType; + data->status = status; + + ret = QueueWork(queue, ProcessDeviceStatusReceived, (uint8_t *)data, sizeof(QueueStatusData)); + if (ret != WORK_QUEUE_OK) { + SECURITY_LOG_ERROR("ProcessDeviceStatusReceiver, QueueWork failed, ret is %{public}u", ret); + FREE(data); + return; + } +} + +static void MessengerOnNodeStateChange(NodeBasicInfo *info, uint32_t state) +{ + if (info == NULL) { + SECURITY_LOG_ERROR("MessengerOnNodeStateChange procee null input."); + return; + } + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + char udid[UDID_BUF_LEN] = {0}; + if (GetNodeKeyInfo(instance->pkgName, info->networkId, NODE_KEY_UDID, (uint8_t *)udid, UDID_BUF_LEN) != 0) { + SECURITY_LOG_ERROR("MessengerOnNodeStateChange procee get device identity error."); + return; + } + + DeviceIdentify identity = {0, {0}}; + identity.length = UDID_BUF_LEN - 1; + if (memcpy_s(identity.identity, DEVICE_ID_MAX_LEN, udid, UDID_BUF_LEN - 1) != EOK) { + SECURITY_LOG_ERROR("MessengerOnNodeStateChange copy device error"); + } + uint32_t maskId = MaskDeviceIdentity(udid, UDID_BUF_LEN); + SECURITY_LOG_INFO("MessengerOnNodeStateChange device(%{public}x*** change to %{public}s, deviceType is %{public}d)", + maskId, (state == EVENT_NODE_STATE_ONLINE) ? "online" : "offline", info->deviceTypeId); + + ProcessDeviceStatusReceiver(&identity, state, info->deviceTypeId); +} + +static void MessengerOnNodeOnline(NodeBasicInfo *info) +{ + return MessengerOnNodeStateChange(info, EVENT_NODE_STATE_ONLINE); +} + +static void MessengerOnNodeOffline(NodeBasicInfo *info) +{ + return MessengerOnNodeStateChange(info, EVENT_NODE_STATE_OFFLINE); +} + +static void MessengerOnNodeBasicInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info) +{ + // just do nothing +} + +bool InitDeviceStatusManager(WorkQueue *queue, const char *pkgName, DeviceStatusReceiver deviceStatusReceiver) +{ + if (deviceStatusReceiver == NULL) { + return false; + } + + DeviceStatusManager *instance = GetDeviceManagerInstance(); + instance->pkgName = pkgName; + instance->deviceStatusReceiver = deviceStatusReceiver; + instance->queue = queue; + + int try = 0; + int32_t ret = RegNodeDeviceStateCb(pkgName, (INodeStateCb *)&instance->nodeStateCb); + while (ret != 0 && try < MAX_TRY_TIMES) { + MessengerSleep(1); // sleep 1 second and try again + ret = RegNodeDeviceStateCb(pkgName, (INodeStateCb *)&instance->nodeStateCb); + try++; + } + + if (ret != 0) { + SECURITY_LOG_ERROR("InitDeviceManager RegNodeDeviceStateCb failed = %{public}d", ret); + return false; + } + + SECURITY_LOG_INFO("InitDeviceManager RegNodeDeviceStateCb success"); + return true; +} + +bool DeInitDeviceStatusManager() +{ + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + int32_t ret = UnregNodeDeviceStateCb((INodeStateCb *)&instance->nodeStateCb); + if (ret != 0) { + SECURITY_LOG_ERROR("DeInitDeviceManager UnregNodeDeviceStateCb failed = %{public}d", ret); + return false; + } + instance->pkgName = NULL; + instance->deviceStatusReceiver = NULL; + instance->queue = NULL; + DestroyWorkQueue(instance->queue); + + SECURITY_LOG_INFO("DeInitDeviceManager UnregNodeDeviceStateCb success"); + return true; +} + +static bool MessengerConvertNodeToIdentity(const NodeBasicInfo *node, DeviceIdentify *devId) +{ + if ((node == NULL) || (devId == NULL)) { + return false; + } + char udid[UDID_BUF_LEN] = {0}; + + DeviceStatusManager *instance = GetDeviceManagerInstance(); + if (GetNodeKeyInfo(instance->pkgName, node->networkId, NODE_KEY_UDID, (uint8_t *)udid, UDID_BUF_LEN) != 0) { + SECURITY_LOG_ERROR("MessengerGetSelfDeviceIdentify GetNodeKeyInfo error."); + return false; + } + + if (memcpy_s(devId->identity, DEVICE_ID_MAX_LEN, udid, DEVICE_ID_MAX_LEN) != EOK) { + SECURITY_LOG_ERROR("MessengerGetSelfDeviceIdentify memcpy error"); + return false; + } + devId->length = DEVICE_ID_MAX_LEN; + return true; +} + +bool MessengerGetDeviceOnlineStatus(const DeviceIdentify *devId, uint32_t *devType) +{ + if (devId == NULL) { + return false; + } + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + NodeBasicInfo *infoList = NULL; + + int infoListLen = 0; + int32_t ret = GetAllNodeDeviceInfo(instance->pkgName, &infoList, &infoListLen); + if (ret != 0) { + SECURITY_LOG_ERROR("MessengerGetDeviceOnlineStatus GetAllNodeDeviceInfo failed = %{public}d", ret); + return false; + } + + bool find = false; + for (int loop = 0; loop < infoListLen; loop++) { + const NodeBasicInfo *node = infoList + loop; + DeviceIdentify curr = {DEVICE_ID_MAX_LEN, {0}}; + bool convert = MessengerConvertNodeToIdentity(node, &curr); + if (convert != true) { + continue; + } + + if (IsSameDevice(devId, &curr)) { + find = true; + break; + } + } + + if (infoList != NULL) { + FreeNodeInfo(infoList); + } + return find; +} + +bool MessengerGetSelfDeviceIdentify(DeviceIdentify *devId, uint32_t *devType) +{ + if (devId == NULL || devType == NULL) { + return false; + } + + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + NodeBasicInfo info; + int32_t ret = GetLocalNodeDeviceInfo(instance->pkgName, &info); + if (ret != 0) { + SECURITY_LOG_ERROR("MessengerGetSelfDeviceIdentify GetLocalNodeDeviceInfo failed = %{public}d", ret); + return false; + } + + bool convert = MessengerConvertNodeToIdentity(&info, devId); + if (convert == false) { + return false; + } + *devType = info.deviceTypeId; + + uint32_t maskId = MaskDeviceIdentity((const char *)&devId->identity[0], UDID_BUF_LEN); + SECURITY_LOG_DEBUG("MessengerGetSelfDeviceIdentify device %{public}x***, deviceType is %{public}d", maskId, + info.deviceTypeId); + return true; +} + +void MessengerForEachDeviceProcess(const DeviceProcessor processor, void *para) +{ + if (processor == NULL) { + return; + } + DeviceStatusManager *instance = GetDeviceManagerInstance(); + + NodeBasicInfo *infoList = NULL; + + int infoListLen = 0; + int32_t ret = GetAllNodeDeviceInfo(instance->pkgName, &infoList, &infoListLen); + if (ret != 0) { + SECURITY_LOG_ERROR("MessengerForEachDeviceProcess GetAllNodeDeviceInfo failed = %{public}d", ret); + return; + } + + for (int loop = 0; loop < infoListLen; loop++) { + const NodeBasicInfo *node = infoList + loop; + DeviceIdentify devId = {DEVICE_ID_MAX_LEN, {0}}; + bool convert = MessengerConvertNodeToIdentity(node, &devId); + if (convert == true) { + processor(&devId, node->deviceTypeId, para); + } + } + + if (infoList != NULL) { + FreeNodeInfo(infoList); + } + + return; +} diff --git a/baselib/msglib/src/standard/messenger_device_status_manager.h b/baselib/msglib/src/standard/messenger_device_status_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..8b3d12d925aaebae57c655bd1b9449b1e126d5ad --- /dev/null +++ b/baselib/msglib/src/standard/messenger_device_status_manager.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 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 SEC_MESSENGER_DEVICE_STATUS_MANAGER_H +#define SEC_MESSENGER_DEVICE_STATUS_MANAGER_H + +#include "messenger.h" + +#include "utils_work_queue.h" + +#ifdef __cplusplus +extern "C" { +#endif + +bool InitDeviceStatusManager(WorkQueue *queue, const char *pkgName, DeviceStatusReceiver deviceStatusReceiver); + +bool DeInitDeviceStatusManager(); + +bool MessengerGetDeviceOnlineStatus(const DeviceIdentify *devId, uint32_t *devType); + +bool MessengerGetSelfDeviceIdentify(DeviceIdentify *devId, uint32_t *devType); + +void MessengerForEachDeviceProcess(const DeviceProcessor processor, void *para); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_MESSENGER_DEVICE_STATUS_MANAGER_H diff --git a/baselib/msglib/src/standard/messenger_impl.c b/baselib/msglib/src/standard/messenger_impl.c new file mode 100644 index 0000000000000000000000000000000000000000..c789c9d81b1aa86bab0c04d1d26d6cceaad0b83e --- /dev/null +++ b/baselib/msglib/src/standard/messenger_impl.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2021 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 "messenger_impl.h" + +#include + +#include "securec.h" +#include "utils_log.h" +#include "utils_mem.h" +#include "utils_work_queue.h" + +#include "messenger.h" +#include "messenger_device_session_manager.h" +#include "messenger_device_status_manager.h" + +#define MESSENGER_MAGIC_HEAD 0x1234abcd +#define MESSENGER_PROCESS_QUEUE_SIZE 256 +typedef struct Messenger { + uint32_t magicHead; + WorkQueue *processQueue; +} Messenger; + +Messenger *CreateMessengerImpl(const MessengerConfig *cfg) +{ + if (cfg == NULL) { + SECURITY_LOG_ERROR("CreateMessengerImpl error para"); + return NULL; + } + + WorkQueue *processQueue = CreateWorkQueue(MESSENGER_PROCESS_QUEUE_SIZE); + if (processQueue == NULL) { + return NULL; + } + + bool result = InitDeviceSessionManager(processQueue, cfg->pkgName, cfg->sessName, cfg->messageReceiver, + cfg->sendResultNotifier); + if (result == false) { + DestroyWorkQueue(processQueue); + return NULL; + } + + result = InitDeviceStatusManager(processQueue, cfg->pkgName, cfg->statusReceiver); + if (result == false) { + DestroyWorkQueue(processQueue); + return NULL; + } + + Messenger *messenger = MALLOC(sizeof(Messenger)); + if (messenger == NULL) { + DestroyWorkQueue(processQueue); + return NULL; + } + messenger->magicHead = MESSENGER_MAGIC_HEAD; + messenger->processQueue = processQueue; + + return messenger; +} + +void DestroyMessengerImpl(Messenger *messenger) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("DestroyMessengerImpl error para"); + return; + } + DeInitDeviceStatusManager(); + DeInitDeviceSessionManager(); + messenger->magicHead = 0; + DestroyWorkQueue(messenger->processQueue); + FREE(messenger); + return; +} + +bool IsMessengerReadyImpl(const Messenger *messenger) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("IsMessengerReadyImpl error para"); + return false; + } + return true; +} + +void SendMsgToImpl(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, + uint32_t msgLen) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("SendMsgToImpl error para"); + return; + } + MessengerSendMsgTo(transNo, devId, msg, msgLen); +} + +bool GetDeviceOnlineStatusImpl(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("GetDeviceOnlineStatusImpl error para"); + return false; + } + + return MessengerGetDeviceOnlineStatus(devId, devType); +} + +bool GetSelfDeviceIdentifyImpl(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("GetSelfDeviceIdentifyImpl error para"); + return false; + } + + return MessengerGetSelfDeviceIdentify(devId, devType); +} + +void ForEachDeviceProcessImpl(const Messenger *messenger, const DeviceProcessor processor, void *para) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("ForEachDeviceProcessImpl error para"); + return; + } + + return MessengerForEachDeviceProcess(processor, para); +} + +bool GetDeviceStatisticInfoImpl(const Messenger *messenger, const DeviceIdentify *devId, StatisticInformation *info) +{ + if (messenger == NULL || messenger->magicHead != MESSENGER_MAGIC_HEAD) { + SECURITY_LOG_ERROR("GetDeviceStatisticInfoImpl error para"); + return false; + } + return true; +} diff --git a/baselib/msglib/src/standard/messenger_utils.h b/baselib/msglib/src/standard/messenger_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..229a8cee705495e00310c13263e752fcec24e199 --- /dev/null +++ b/baselib/msglib/src/standard/messenger_utils.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2021 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 SEC_MESSENGER_UTILS_H +#define SEC_MESSENGER_UTILS_H + +#include +#include +#include + +#include "securec.h" +#include "utils_hexstring.h" + +#include "messenger.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_TRY_TIMES 512 + +static inline uint32_t MaskDeviceIdentity(const char *deviceId, uint32_t length) +{ +#define MASK_LEN 4 +#define SHIFT_LENGTH 8 +#define MASK_LOW 0x00ff +#define MASK_HIGH 0xff00 + if (deviceId == NULL || length < MASK_LEN) { + return 0; + } + + uint16_t maskId = 0; + HexStringToByte(deviceId, MASK_LEN, (uint8_t *)&maskId, sizeof(maskId)); + return ((maskId & MASK_HIGH) >> SHIFT_LENGTH) | ((maskId & MASK_LOW) << SHIFT_LENGTH); +} + +static inline void MessengerSleep(uint32_t seconds) +{ + int ret; + struct timeval tm = { + .tv_sec = seconds, + .tv_usec = 0, + }; + do { + ret = select(0, NULL, NULL, NULL, &tm); + } while ((ret == -1) && (errno == EINTR)); +} + +static inline bool IsSameDevice(const DeviceIdentify *left, const DeviceIdentify *right) +{ + if ((left == NULL) || (right == NULL)) { + return false; + } + + if (left->length != right->length) { + return false; + } + + if (memcmp(left->identity, right->identity, left->length) != 0) { + return false; + } + + return true; +} + +#ifdef __cplusplus +} +#endif + +#endif // SEC_MESSENGER_UTILS_H diff --git a/baselib/utils/BUILD.gn b/baselib/utils/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..f359897fe3723773ec6df8d624ccec5eebdb084c --- /dev/null +++ b/baselib/utils/BUILD.gn @@ -0,0 +1,47 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +config("utils_static_config") { + visibility = [ ":*" ] + include_dirs = [ "include" ] +} + +# utils static lib +ohos_static_library("utils_static") { + sources = [ + "src/utils_base64.c", + "src/utils_datetime.c", + "src/utils_hexstring.c", + "src/utils_json.c", + "src/utils_state_machine.c", + "src/utils_timer.cpp", + "src/utils_tlv.c", + "src/utils_work_queue.c", + ] + + include_dirs = [ "include" ] + + public_configs = [ ":utils_static_config" ] + + deps = [ "//third_party/cJSON:cjson_static" ] + + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/baselib/utils/include/utils_base64.h b/baselib/utils/include/utils_base64.h new file mode 100644 index 0000000000000000000000000000000000000000..61d9e3bbea2c001bf5e69ddc5fec8889165a4bca --- /dev/null +++ b/baselib/utils/include/utils_base64.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_BASE64_H +#define SEC_UTILS_BASE64_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t Base64DecodeApp(const uint8_t *src, uint8_t **to); + +uint8_t *Base64EncodeApp(const uint8_t *from, uint32_t fromLen); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_BASE64_H \ No newline at end of file diff --git a/baselib/utils/include/utils_datetime.h b/baselib/utils/include/utils_datetime.h new file mode 100644 index 0000000000000000000000000000000000000000..d64a128c9ee0638d146a2c2df2c6e7c688e5b633 --- /dev/null +++ b/baselib/utils/include/utils_datetime.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_DATETIME_H +#define SEC_UTILS_DATETIME_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DateTime { + uint16_t hour; + uint16_t min; + uint16_t sec; + uint16_t msec; + uint16_t year; + uint16_t mon; + uint16_t day; +} DateTime; + +uint64_t GetMillisecondSinceBoot(); + +uint64_t GetMillisecondSince1970(); + +bool GetDateTimeByMillisecondSince1970(uint64_t input, DateTime *datetime); + +bool GetDateTimeByMillisecondSinceBoot(uint64_t input, DateTime *datetime); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_DATETIME_H \ No newline at end of file diff --git a/baselib/utils/include/utils_hexstring.h b/baselib/utils/include/utils_hexstring.h new file mode 100644 index 0000000000000000000000000000000000000000..a760c9d416445ccd381299bc8e31432425a6d684 --- /dev/null +++ b/baselib/utils/include/utils_hexstring.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_HEX_STRING_H +#define SEC_UTILS_HEX_STRING_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ByteToHexString(const uint8_t *hex, uint32_t hexLen, uint8_t *str, uint32_t strLen); + +int32_t HexStringToByte(const char *str, uint32_t strLen, uint8_t *hex, uint32_t hexLen); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_HEX_STRING_H \ No newline at end of file diff --git a/baselib/utils/include/utils_json.h b/baselib/utils/include/utils_json.h new file mode 100644 index 0000000000000000000000000000000000000000..4ed7f5db540029d84646401873dba5836c27de39 --- /dev/null +++ b/baselib/utils/include/utils_json.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_JSON_H +#define SEC_UTILS_JSON_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *JsonHandle; + +JsonHandle CreateJson(const char *data); +void DestroyJson(JsonHandle handle); + +int32_t GetJsonFieldInt(JsonHandle handle, const char *field); +int32_t GetJsonFieldIntArray(JsonHandle handle, const char *field, int32_t *array, int32_t arrayLen); +const char *GetJsonFieldString(JsonHandle handle, const char *field); +JsonHandle GetJsonFieldJson(JsonHandle handle, const char *field); + +void AddFieldIntToJson(JsonHandle handle, const char *field, int32_t value); +void AddFieldIntArrayToJson(JsonHandle handle, const char *field, const int32_t *array, int32_t arrayLen); +void AddFieldStringToJson(JsonHandle handle, const char *field, const char *value); +void AddFieldJsonToJson(JsonHandle handle, const char *field, JsonHandle json); + +char *ConvertJsonToString(JsonHandle handle); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_JSON_H \ No newline at end of file diff --git a/baselib/utils/include/utils_list.h b/baselib/utils/include/utils_list.h new file mode 100644 index 0000000000000000000000000000000000000000..9678d9c08362b86fa9f639631d60888a0bfe571d --- /dev/null +++ b/baselib/utils/include/utils_list.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_LIST_H +#define SEC_UTILS_LIST_H + +typedef struct TagListHead { + struct TagListHead *next; + struct TagListHead *prev; +} ListHead; + +typedef ListHead ListNode; + +static inline void AddListNode(ListNode *item, ListNode *where) +{ + item->next = where->next; + item->prev = where; + where->next = item; + item->next->prev = item; +} + +static inline void AddListNodeBefore(ListNode *item, ListNode *where) +{ + AddListNode(item, where->prev); +} + +static inline void RemoveListNode(ListNode *item) +{ + item->prev->next = item->next; + item->next->prev = item->prev; +} + +static inline int IsEmptyList(ListHead *head) +{ + return head->next == head; +} + +static inline void InitListHead(ListHead *head) +{ + head->next = head; + head->prev = head; +} + +#define INIT_LIST(list) \ + { \ + &(list), &(list) \ + } + +#define FOREACH_LIST_NODE(item, head) for ((item) = (head)->next; (item) != (head); (item) = (item)->next) + +#define FOREACH_LIST_NODE_SAFE(item, head, temp) \ + for ((item) = (head)->next, (temp) = (item)->next; (item) != (head); (item) = (temp), (temp) = (item)->next) + +#define LIST_ENTRY(item, type, member) ((type *)((char *)(item) - (char *)(&((type *)0)->member))) + +#endif /* SEC_UTILS_LIST_H */ \ No newline at end of file diff --git a/baselib/utils/include/utils_log.h b/baselib/utils/include/utils_log.h new file mode 100644 index 0000000000000000000000000000000000000000..d63dc589fae97abc052d4be6511f55ced698a0bd --- /dev/null +++ b/baselib/utils/include/utils_log.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_LOG_H +#define SEC_UTILS_LOG_H + +#include "hilog/log.h" + +#ifndef __cplusplus +#ifdef LOG_TAG +#undef LOG_TAG +#endif +#define LOG_TAG "DSLM_SERVICE" + +#ifdef LOG_DOMAIN +#undef LOG_DOMAIN +#endif +#define LOG_DOMAIN 0xD002F00 + +#define SECURITY_LOG_DEBUG(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_ERROR(fmt, ...) HILOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_FATAL(fmt, ...) HILOG_FATAL(LOG_CORE, fmt, ##__VA_ARGS__) + +#else // __cplusplus +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD002F00, "DSLM_SERVICE"}; + +#define SECURITY_LOG_DEBUG(fmt, ...) OHOS::HiviewDFX::HiLog::Debug(LABEL, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_INFO(fmt, ...) OHOS::HiviewDFX::HiLog::Info(LABEL, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_WARN(fmt, ...) OHOS::HiviewDFX::HiLog::Warn(LABEL, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_ERROR(fmt, ...) OHOS::HiviewDFX::HiLog::Error(LABEL, fmt, ##__VA_ARGS__) +#define SECURITY_LOG_FATAL(fmt, ...) OHOS::HiviewDFX::HiLog::Fatal(LABEL, fmt, ##__VA_ARGS__) + +#endif // __cplusplus +#endif // SEC_UTILS_LOG_H diff --git a/baselib/utils/include/utils_mem.h b/baselib/utils/include/utils_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..277b5bab2946f8ae33129dccf45228b739cd05b3 --- /dev/null +++ b/baselib/utils/include/utils_mem.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_MEM_H +#define SEC_UTILS_MEM_H + +#include + +#define MALLOC malloc +#define CALLOC calloc +#define FREE free + +#endif // SEC_UTILS_MEM_H \ No newline at end of file diff --git a/baselib/utils/include/utils_mutex.h b/baselib/utils/include/utils_mutex.h new file mode 100644 index 0000000000000000000000000000000000000000..5167ce7621cc759fc6918d4d613abbf68441caa8 --- /dev/null +++ b/baselib/utils/include/utils_mutex.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_COMMON_MUTEX_H +#define SEC_UTILS_COMMON_MUTEX_H + +#include + +#include "utils_log.h" + +#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +#define RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + +#define INITED_MUTEX \ + { \ + MUTEX_INITIALIZER \ + } + +#define IRECURSIVE_INITED_MUTEX \ + { \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ + } + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct Mutex { + pthread_mutex_t mutex; +} Mutex; + +inline static void InitMutex(Mutex *mutex) +{ + int ret = pthread_mutex_init(&mutex->mutex, NULL); + if (ret != 0) { + SECURITY_LOG_ERROR("InitMutex pthread_mutex_init error"); + } +} + +inline static void InitRecursiveMutex(Mutex *mutex) +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + int ret = pthread_mutex_init(&mutex->mutex, &attr); + if (ret != 0) { + SECURITY_LOG_ERROR("InitRecursiveMutex pthread_mutex_init error"); + } +} + +inline static void LockMutex(Mutex *mutex) +{ + int ret = pthread_mutex_lock(&(mutex->mutex)); + if (ret != 0) { + SECURITY_LOG_ERROR("LockMutex pthread_mutex_lock error"); + } +} + +inline static void UnlockMutex(Mutex *mutex) +{ + int ret = pthread_mutex_unlock(&(mutex->mutex)); + if (ret != 0) { + SECURITY_LOG_ERROR("UnlockMutex pthread_mutex_unlock error"); + } +} + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_COMMON_MUTEX_H diff --git a/baselib/utils/include/utils_state_machine.h b/baselib/utils/include/utils_state_machine.h new file mode 100644 index 0000000000000000000000000000000000000000..74e97be9123235de77cb4d749df56c79e94dd184 --- /dev/null +++ b/baselib/utils/include/utils_state_machine.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_FINITE_STATE_MACHINE_H +#define SEC_UTILS_FINITE_STATE_MACHINE_H + +#include +#include + +#include "utils_list.h" +#include "utils_mutex.h" + +typedef struct StateMachine StateMachine; + +typedef bool (*StateMachineProcessFunc)(const StateMachine *machine, uint32_t event, const void *para); + +typedef struct { + uint32_t state; + uint32_t event; + StateMachineProcessFunc process; + uint32_t nextStateT; + uint32_t nextStateF; +} StateNode; + +typedef struct StateMachine { + uint32_t currState; + uint32_t machineId; + bool isScheduling; + ListHead pendingEventList; + Mutex mutex; +} StateMachine; + +void InitStateMachine(StateMachine *machine, uint32_t machineId, uint32_t initState); + +void ScheduleMachine(const StateNode *nodes, uint32_t nodeCnt, StateMachine *machine, uint32_t event, const void *para); + +#define STATE_MACHINE_ENTRY(item, type, member) ((type *)((char *)(item) - (char *)(&((type *)0)->member))) + +#endif // SEC_UTILS_FINITE_STATE_MACHINE_H diff --git a/baselib/utils/include/utils_timer.h b/baselib/utils/include/utils_timer.h new file mode 100644 index 0000000000000000000000000000000000000000..0b1871ce906928224d7db4b1e679762e1b15655d --- /dev/null +++ b/baselib/utils/include/utils_timer.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_TIMER_H +#define SEC_UTILS_TIMER_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uintptr_t TimerHandle; + +typedef void (*TimerProc)(const void *context); + +TimerHandle StartPeriodicTimerTask(uint32_t interval, TimerProc callback, const void *context); + +TimerHandle StartOnceTimerTask(uint32_t interval, TimerProc callback, const void *context); + +void StopTimerTask(TimerHandle handle); + +#ifdef __cplusplus +} +#endif + +#endif // SEC_UTILS_TIMER_H \ No newline at end of file diff --git a/baselib/utils/include/utils_tlv.h b/baselib/utils/include/utils_tlv.h new file mode 100644 index 0000000000000000000000000000000000000000..f245c36202ea359947075ba10db19eb34322037c --- /dev/null +++ b/baselib/utils/include/utils_tlv.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_TLV_H +#define SEC_UTILS_TLV_H + +#include + +#define TLV_OK 0 +#define TLV_ERR 1001 +#define TLV_ERR_INVALID_PARA 1002 +#define TLV_ERR_PARSE_PAYLOAD_ERR 1003 +#define TLV_ERR_BUFF_NO_ENOUGH 1004 + +typedef struct TlvCommon { + uint16_t tag; + uint16_t len; + void *value; +} TlvCommon; + +uint32_t Serialize(const TlvCommon *tlv, uint32_t tlvCount, uint8_t *buff, uint32_t maxBuffSize, uint32_t *buffSize); + +uint32_t Deserialize(const uint8_t *buff, uint32_t buffSize, TlvCommon *tlv, uint32_t maxTlvCount, uint32_t *tlvCount); + +#endif // SEC_UTILS_TLV_H \ No newline at end of file diff --git a/baselib/utils/include/utils_work_queue.h b/baselib/utils/include/utils_work_queue.h new file mode 100644 index 0000000000000000000000000000000000000000..6f4b9d65cc3fb3b527aa29cc5085be4dee88310b --- /dev/null +++ b/baselib/utils/include/utils_work_queue.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 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 SEC_UTILS_WORK_QUEUE_H +#define SEC_UTILS_WORK_QUEUE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define WORK_QUEUE_OK 0 +#define WORK_QUEUE_ERROR (6600) +#define WORK_QUEUE_NULL_PTR (WORK_QUEUE_ERROR + 0x1) +#define WORK_QUEUE_MALLOC_ERR (WORK_QUEUE_ERROR + 0x2) +#define WORK_QUEUE_THREAD_COND_ERR (WORK_QUEUE_ERROR + 0x3) +#define WORK_QUEUE_THREAD_JOIN_ERR (WORK_QUEUE_ERROR + 0x4) +#define WORK_QUEUE_STATE_ERR (WORK_QUEUE_ERROR + 0x5) +#define WORK_QUEUE_FULL (WORK_QUEUE_ERROR + 0x6) + +typedef struct WorkQueue WorkQueue; + +typedef void (*WorkProcess)(const uint8_t *data, uint32_t len); + +uint32_t QueueWork(WorkQueue *queue, WorkProcess process, uint8_t *data, uint32_t length); + +WorkQueue *CreateWorkQueue(uint32_t capacity); + +uint32_t DestroyWorkQueue(WorkQueue *queue); + +#ifdef __cplusplus +} +#endif +#endif /* SEC_UTILS_WORK_QUEUE_H */ \ No newline at end of file diff --git a/baselib/utils/src/utils_base64.c b/baselib/utils/src/utils_base64.c new file mode 100644 index 0000000000000000000000000000000000000000..7b0a73fc4ea19f06b1525b9b036306d022e4c4e7 --- /dev/null +++ b/baselib/utils/src/utils_base64.c @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2021 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 "utils_base64.h" + +#include +#include + +#include "utils_log.h" +#include "utils_mem.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_MALLOC_LEN (1 * 1024 * 1024) + +static const char *g_base64EncodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const uint8_t g_base64DecodeTable[256] = { /* 256 due to character size */ + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 62, 65, 65, 65, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 65, 65, 65, 0, 65, 65, + 65, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 65, 65, 65, 65, 65, + 65, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65 +}; + +/* + * This function is for Base64 encoding based on the public algorithm + */ +static int32_t Base64Encode(const uint8_t *from, uint32_t fromLen, uint8_t *to, uint32_t toCheckLen) +{ + bool isInvalidParam = ((from == NULL) || (to == NULL) || (fromLen == 0)); + if (isInvalidParam) { + return -1; + } + + uint32_t tmpLen = fromLen; + uint32_t toLen = ((tmpLen + 2) / 3); /* Base64 encode size, add 2 for padding, and divided by 3 */ + int padding = tmpLen % 3; /* len % 3 to get the padding size. This must be signed type! */ + padding = (padding == 0) ? 0 : (3 - padding); /* For the padding block out of 3 */ + if (toLen >= (toLen * 4)) { /* For integer overflow and toLen can not be 0, with 4X */ + return -1; + } + toLen *= 4; /* For 4 blocks */ + if (toCheckLen < toLen) { + return -1; + } + + uint32_t j = 0; + for (uint32_t i = 0; i < fromLen;) { + uint32_t a = (i < fromLen) ? (uint8_t)from[i] : 0; + i++; + uint32_t b = (i < fromLen) ? (uint8_t)from[i] : 0; + i++; + uint32_t c = (i < fromLen) ? (uint8_t)from[i] : 0; + i++; + uint32_t byte = (((a << 16) & 0x00FF0000) | ((b << 8) & 0x0000FF00) | ((c << 0) & 0x000000FF)); /* 16, 8 */ + + to[j++] = g_base64EncodeTable[(byte >> 18) & 0x3F]; /* get the 1st block by shift 18 */ + to[j++] = g_base64EncodeTable[(byte >> 12) & 0x3F]; /* get the 2nd block by shift 12 */ + to[j++] = g_base64EncodeTable[(byte >> 6) & 0x3F]; /* get the 3rd block by shift 6 */ + to[j++] = g_base64EncodeTable[(byte >> 0) & 0x3F]; + } + + if (padding-- > 0) { + to[toLen - 1] = '='; /* padding the -1 to "=" */ + } + if (padding-- > 0) { + to[toLen - 2] = '='; /* padding the -2 to "=" */ + } + + return toLen; +} + +/* + * This function is for Base64 decoding based on the public algorithm + */ +static int32_t Base64Decode(const uint8_t *from, uint8_t *to, uint32_t toCheckLen) +{ + bool isInvalidParam = ((from == NULL) || (to == NULL)); + if (isInvalidParam) { + return -1; + } + + uint32_t fromLen = strlen((char *)from); + // base64 encode Valid data Length is 4 + bool isInvalidLength = ((fromLen < 4) || ((fromLen % 4) != 0)); + if (isInvalidLength) { + return -1; + } + + uint32_t toLen = fromLen / 4 * 3; /* Base64 decode size */ + if (from[fromLen - 1] == '=') { /* if last bit is null, make it "=" */ + toLen--; + } + if (from[fromLen - 2] == '=') { /* if Second-to-last bit is null, make it "=" */ + toLen--; + } + if (toCheckLen < toLen) { + return -1; + } + + uint32_t j = 0; + for (uint32_t i = 0; i < fromLen;) { + uint32_t a = g_base64DecodeTable[from[i++]]; + uint32_t b = g_base64DecodeTable[from[i++]]; + uint32_t c = g_base64DecodeTable[from[i++]]; + uint32_t d = g_base64DecodeTable[from[i++]]; + + // 64 is decode table max valid num. + bool isInvalidVariable = ((a > 64) || (b > 64) || (c > 64) || (d > 64)); + if (isInvalidVariable) { + return -1; + } + + // Converts four 6-bit data into three 8-bit data + uint32_t byte = + (((a << 18) & 0x00FC0000) | ((b << 12) & 0x0003F000) | ((c << 6) & 0x00000FC0) | ((d << 0) & 0x0000003F)); + + if (j < toLen) { + to[j++] = (byte >> 16) & 0xFF; + } + if (j < toLen) { + to[j++] = (byte >> 8) & 0xFF; + } + if (j < toLen) { + to[j++] = (byte >> 0) & 0xFF; + } + } + to[toLen] = '\0'; + return toLen; +} + +uint8_t *Base64EncodeApp(const uint8_t *from, uint32_t fromLen) +{ + if (from == NULL) { + SECURITY_LOG_DEBUG("Unexpected nullptr!"); + return NULL; + } + + uint32_t outSize = (fromLen + 2) / 3 * 4; // get base64 encode size + if (outSize + 1 > MAX_MALLOC_LEN) { + SECURITY_LOG_DEBUG("Invalid MALLOC length!"); + return NULL; + } + uint8_t *out = (uint8_t *)MALLOC(outSize + 1); + if (out == NULL) { + SECURITY_LOG_DEBUG("Memory allocation failed!"); + return NULL; + } + + int realLen = Base64Encode(from, fromLen, out, outSize); + if (realLen < 0) { + SECURITY_LOG_DEBUG("Base64EncodeApp fail"); + FREE(out); + return NULL; + } + out[realLen] = '\0'; + return out; +} + +int32_t Base64DecodeApp(const uint8_t *src, uint8_t **to) +{ + if ((src == NULL) || (to == NULL)) { + SECURITY_LOG_DEBUG("Unexpected nullptr!"); + return 0; + } + + uint32_t decodedLen = strlen((char *)src) / 4 * 3; /* Base64 Decode size */ + if (decodedLen + 1 > MAX_MALLOC_LEN) { + SECURITY_LOG_DEBUG("Base64DecodeApp decodedLen err"); + return 0; + } + + uint8_t *decoded = (uint8_t *)MALLOC(decodedLen + 1); + if (decoded == NULL) { + SECURITY_LOG_DEBUG("Base64DecodeApp MALLOC fail"); + return 0; + } + + int realLen = Base64Decode(src, decoded, decodedLen); + if (realLen < 0) { + SECURITY_LOG_DEBUG("Base64DecodeApp fail"); + FREE(decoded); + return 0; + } + + decoded[realLen] = '\0'; + *to = decoded; + return realLen; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/baselib/utils/src/utils_datetime.c b/baselib/utils/src/utils_datetime.c new file mode 100644 index 0000000000000000000000000000000000000000..30bed01b98692ba82f30738f7d81b6be7f3fef9d --- /dev/null +++ b/baselib/utils/src/utils_datetime.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2021 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 "utils_datetime.h" + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SEC_TO_NANOSEC 1000000000 +#define SEC_TO_MICROSEC 1000000 +#define SEC_TO_MILLISEC 1000 +#define MILLISEC_TO_NANOSEC 1000000 +#define MILLISEC_TO_USEC 1000 +#define MICROSEC_TO_NANOSEC 1000 + +uint64_t GetMillisecondSinceBoot() +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC); +} + +uint64_t GetMillisecondSince1970() +{ + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return ts.tv_sec * SEC_TO_MILLISEC + ts.tv_nsec / MILLISEC_TO_NANOSEC; +} + +bool GetDateTimeByMillisecondSince1970(uint64_t input, DateTime *datetime) +{ + if (datetime == NULL) { + return false; + } + struct tm tm; + time_t time = (time_t)(input / SEC_TO_MILLISEC); + localtime_r(&time, &tm); + + datetime->year = tm.tm_year + 1900; // need add 1900 + datetime->mon = tm.tm_mon + 1; + datetime->day = tm.tm_mday; + datetime->hour = tm.tm_hour; + datetime->min = tm.tm_min; + datetime->sec = tm.tm_sec; + datetime->msec = input % SEC_TO_MILLISEC; + return true; +} +bool GetDateTimeByMillisecondSinceBoot(uint64_t input, DateTime *datetime) +{ + if (datetime == NULL) { + return false; + } + static uint64_t compensate = 0; + if (compensate == 0) { + compensate = GetMillisecondSince1970() - GetMillisecondSinceBoot(); + } + + return GetDateTimeByMillisecondSince1970(input + compensate, datetime); +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/baselib/utils/src/utils_hexstring.c b/baselib/utils/src/utils_hexstring.c new file mode 100644 index 0000000000000000000000000000000000000000..84eb8a9d87eb9af2927840e459073492af6ac378 --- /dev/null +++ b/baselib/utils/src/utils_hexstring.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 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 "utils_hexstring.h" + +#include + +#include "utils_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ERR (-1) +#define OK 0 + +#define BYTE_TO_HEX_OPER_LENGTH 2 +#define MAX_MALLOC_LEN (1 * 1024 * 1024) + +static char HexToChar(uint8_t hex) +{ + return (hex > 9) ? (hex + 0x37) : (hex + 0x30); /* check if bigger than 9, then add 0x37 or 0x30 */ +} + +void ByteToHexString(const uint8_t *hex, uint32_t hexLen, uint8_t *str, uint32_t strLen) +{ + if (strLen < hexLen * BYTE_TO_HEX_OPER_LENGTH) { + return; + } + + for (uint32_t i = 0; i < hexLen; i++) { + str[i * BYTE_TO_HEX_OPER_LENGTH] = HexToChar((hex[i] & 0xF0) >> 4); /* shift 4 right for filling */ + str[i * BYTE_TO_HEX_OPER_LENGTH + 1] = HexToChar(hex[i] & 0x0F); /* get low four bits */ + } +} + +int32_t HexStringToByte(const char *str, uint32_t strLen, uint8_t *hex, uint32_t hexLen) +{ + if (strLen % BYTE_TO_HEX_OPER_LENGTH) { /* even number or not */ + return ERR; + } + uint32_t outLen = strLen / BYTE_TO_HEX_OPER_LENGTH; + + if (hexLen < outLen) { /* test the length */ + SECURITY_LOG_DEBUG("HexStringToByte length error"); + return ERR; + } + + uint8_t nibble[BYTE_TO_HEX_OPER_LENGTH]; /* create array */ + + for (uint32_t i = 0; i < outLen; i++) { + nibble[0] = str[i * BYTE_TO_HEX_OPER_LENGTH]; /* hex conversion */ + nibble[1] = str[i * BYTE_TO_HEX_OPER_LENGTH + 1]; /* hex conversion */ + for (int32_t j = 0; j < BYTE_TO_HEX_OPER_LENGTH; j++) { /* iterate through array */ + if ((nibble[j] <= 'F') && (nibble[j] >= 'A')) { + nibble[j] = nibble[j] - 'A' + 10; /* decimal conversion, add 10 */ + } else if ((nibble[j] <= 'f') && (nibble[j] >= 'a')) { + nibble[j] = nibble[j] - 'a' + 10; /* decimal conversion, add 10 */ + } else if ((nibble[j] >= '0') && (nibble[j] <= '9')) { + nibble[j] = nibble[j] - '0'; + } else { + return ERR; + } + } + hex[i] = nibble[0] << 4; /* Set the high nibble, shift 4 */ + hex[i] |= nibble[1]; /* Set the low nibble */ + } + return OK; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/baselib/utils/src/utils_json.c b/baselib/utils/src/utils_json.c new file mode 100644 index 0000000000000000000000000000000000000000..df8015498f0bd90e76c019b5dd92d983d5386340 --- /dev/null +++ b/baselib/utils/src/utils_json.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021 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 "utils_json.h" + +#include "cJSON.h" + +#ifdef __cplusplus +extern "C" { +#endif + +JsonHandle CreateJson(const char *data) +{ + cJSON *root = NULL; + + if (data != NULL) { + root = cJSON_Parse(data); + } else { + root = cJSON_CreateObject(); + } + return (void *)root; +} + +void DestroyJson(JsonHandle handle) +{ + if (handle != NULL) { + cJSON_Delete((cJSON *)handle); + } +} + +int32_t GetJsonFieldInt(JsonHandle handle, const char *field) +{ + int32_t ret = -1; + + if (handle == NULL) { + return ret; + } + + if (field == NULL) { + return ((cJSON *)handle)->valueint; + } + + cJSON *objValue = NULL; + + do { + objValue = (cJSON *)GetJsonFieldJson(handle, field); + if (objValue == NULL) { + break; + } + if (!cJSON_IsNumber(objValue)) { + break; + } + ret = objValue->valueint; + } while (0); + + return ret; +} + +int32_t GetJsonFieldIntArray(JsonHandle handle, const char *field, int32_t *array, int32_t arrayLen) +{ + if (handle == NULL || field == NULL || array == NULL) { + return 0; + } + + cJSON *objValue = cJSON_GetObjectItem(handle, field); + if (objValue == NULL) { + return 0; + } + if (!cJSON_IsArray(objValue)){ + return 0; + } + + int size = cJSON_GetArraySize(objValue); + if (size > arrayLen) { + size = arrayLen; + } + int32_t index = 0; + for (int32_t i = 0; i < size; i++) { + cJSON *item = cJSON_GetArrayItem(objValue, i); + if (!cJSON_IsNumber(item)) { + continue; + } + array[index++] = item->valueint; + } + + return index; +} + +const char *GetJsonFieldString(JsonHandle handle, const char *field) +{ + if (handle == NULL) { + return NULL; + } + if (field == NULL) { + return ((cJSON *)handle)->valuestring; + } + cJSON *objValue = NULL; + const char *payload = NULL; + + do { + objValue = (cJSON *)GetJsonFieldJson(handle, field); + if (objValue == NULL) { + break; + } + payload = cJSON_GetStringValue(objValue); + if (payload == NULL) { + break; + } + } while (0); + return payload; +} + +JsonHandle GetJsonFieldJson(JsonHandle handle, const char *field) +{ + return cJSON_GetObjectItem((cJSON *)handle, field); +} + +void AddFieldIntToJson(JsonHandle handle, const char *field, int32_t value) +{ + if (handle == NULL || field == NULL) { + return; + } + (void)cJSON_AddNumberToObject((cJSON *)handle, field, value); +} + +void AddFieldIntArrayToJson(JsonHandle handle, const char *field, const int32_t *array, int32_t arrayLen) +{ + if (handle == NULL || field == NULL || array == NULL) { + return; + } + cJSON *arrayObj = cJSON_CreateIntArray(array, arrayLen); + if (arrayObj == NULL) { + return; + } + (void)cJSON_AddItemToObject((cJSON *)handle, field, arrayObj); +} + +void AddFieldStringToJson(JsonHandle handle, const char *field, const char *value) +{ + if (handle == NULL || field == NULL || value == NULL) { + return; + } + (void)cJSON_AddStringToObject((cJSON *)handle, field, value); +} + +void AddFieldJsonToJson(JsonHandle handle, const char *field, JsonHandle json) +{ + if (handle == NULL || field == NULL || json == NULL) { + return; + } + (void)cJSON_AddItemToObject((cJSON *)handle, field, json); +} + +char *ConvertJsonToString(JsonHandle handle) +{ + if (handle != NULL) { + char *ret = cJSON_PrintUnformatted((cJSON *)handle); + return ret; + } + return NULL; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/baselib/utils/src/utils_state_machine.c b/baselib/utils/src/utils_state_machine.c new file mode 100644 index 0000000000000000000000000000000000000000..f93629dc0f49aaf95c1e0845a12d1404f1f8cd7e --- /dev/null +++ b/baselib/utils/src/utils_state_machine.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2021 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 "utils_state_machine.h" +#include "utils_log.h" +#include "utils_mem.h" + +#include + +typedef struct { + ListNode link; + uint32_t event; + const void *para; +} PendingEvent; + +void InitStateMachine(StateMachine *machine, uint32_t machineId, uint32_t initState) +{ + if (machine == NULL) { + return; + } + machine->machineId = machineId; + machine->isScheduling = false; + machine->currState = initState; + InitListHead(&machine->pendingEventList); + InitRecursiveMutex(&machine->mutex); +} + +static const StateNode *GetScheduleStateNode(const StateNode *nodes, uint32_t nodeCnt, uint32_t state, uint32_t event) +{ + for (uint32_t i = 0; i < nodeCnt; i++) { + const StateNode *node = nodes + i; + if ((node->state == state) && (node->event == event)) { + return node; + } + } + return NULL; +} + +static inline void PushPendingEvent(StateMachine *machine, uint32_t event, const void *para) +{ + PendingEvent *pending = MALLOC(sizeof(PendingEvent)); + if (pending == NULL) { + return; + } + pending->event = event; + pending->para = para; + AddListNodeBefore(&pending->link, &machine->pendingEventList); +} + +static inline bool PopPendingEvent(StateMachine *machine, uint32_t *event, const void **para) +{ + ListHead *head = &machine->pendingEventList; + if (IsEmptyList(head)) { + return false; + } + PendingEvent *pending = LIST_ENTRY(head->next, PendingEvent, link); + RemoveListNode(&pending->link); + *event = pending->event; + *para = pending->para; + FREE(pending); + return true; +} + +void ScheduleMachine(const StateNode *nodes, uint32_t nodeCnt, StateMachine *machine, uint32_t event, const void *para) +{ + // EventPara could be null, need not to check + if ((nodes == NULL) || (nodeCnt == 0) || (machine == NULL)) { + SECURITY_LOG_ERROR("nodes or context is null"); + return; + } + LockMutex(&machine->mutex); + + if (machine->isScheduling) { + PushPendingEvent(machine, event, para); + UnlockMutex(&machine->mutex); + return; + } + + uint32_t state = machine->currState; + const StateNode *node = GetScheduleStateNode(nodes, nodeCnt, state, event); + if (node != NULL) { + bool result = true; + if (node->process != NULL) { + machine->isScheduling = true; + result = node->process(machine, event, para); + machine->isScheduling = false; + } + machine->currState = (result == true) ? node->nextStateT : node->nextStateF; + } + SECURITY_LOG_INFO("Statemachine(%{public}x) schedule state(%{public}u) + event(%{public}u) -> newState(%{public}u)", + machine->machineId, state, event, machine->currState); + uint32_t nextEvent = 0; + const void *nextPara = NULL; + bool isPending = PopPendingEvent(machine, &nextEvent, &nextPara); + UnlockMutex(&machine->mutex); + if (isPending) { + return ScheduleMachine(nodes, nodeCnt, machine, nextEvent, nextPara); + } +} diff --git a/baselib/utils/src/utils_timer.cpp b/baselib/utils/src/utils_timer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3314dc9ae15161d40a8cfb5ed098a398dce75c95 --- /dev/null +++ b/baselib/utils/src/utils_timer.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2021 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 "utils_timer.h" + +#include "singleton.h" +#include "timer.h" + +#include "utils_log.h" + +#ifdef __cplusplus +extern "C" { +#endif + +using namespace OHOS; +class UtilsTimer final : public OHOS::Utils::Timer { + DECLARE_DELAYED_REF_SINGLETON(UtilsTimer) +}; + +UtilsTimer::~UtilsTimer() +{ + this->Shutdown(); +} + +UtilsTimer::UtilsTimer() : Timer("timer_process") +{ + this->Setup(); +} + +void DoTimerProcess(TimerProc callback, const void *context) +{ + if (callback != nullptr) { + callback(const_cast(context)); + } +} + +TimerHandle StartPeriodicTimerTask(uint32_t interval, TimerProc callback, const void *context) +{ + UtilsTimer &st = DelayedRefSingleton::GetInstance(); + uint32_t timerId = st.Register(std::bind(&DoTimerProcess, callback, context), interval, false); + return static_cast(timerId); +} + +TimerHandle StartOnceTimerTask(uint32_t interval, TimerProc callback, const void *context) +{ + UtilsTimer &st = DelayedRefSingleton::GetInstance(); + uint32_t timerId = st.Register(std::bind(&DoTimerProcess, callback, context), interval, true); + return static_cast(timerId); +} + +void StopTimerTask(TimerHandle handle) +{ + UtilsTimer &st = DelayedRefSingleton::GetInstance(); + st.Unregister(static_cast(handle)); +} +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/baselib/utils/src/utils_tlv.c b/baselib/utils/src/utils_tlv.c new file mode 100644 index 0000000000000000000000000000000000000000..a4a3b8b90ce2eaf1b8cc8ebee9ce7bfdfd6384c4 --- /dev/null +++ b/baselib/utils/src/utils_tlv.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2021 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 "utils_tlv.h" + +#include + +#define TLV_TAG_LEN sizeof(uint16_t) +#define TLV_LENGTH_LEN sizeof(uint16_t) +#define TLV_TLV_HEAD_LEN (TLV_TAG_LEN + TLV_LENGTH_LEN) + +static uint8_t *GetNextTlv(const uint8_t *buffer) +{ + return (uint8_t *)buffer + ((TlvCommon *)buffer)->len + TLV_TLV_HEAD_LEN; +} + +static uint8_t *ParseTlv(const uint8_t *buffer, TlvCommon *tlv, const uint8_t *boundary, uint32_t *retCode) +{ + if (buffer + TLV_TLV_HEAD_LEN > boundary) { + *retCode = TLV_ERR_PARSE_PAYLOAD_ERR; + return NULL; + } + if (GetNextTlv(buffer) > boundary) { + *retCode = TLV_ERR_PARSE_PAYLOAD_ERR; + return NULL; + } + tlv->tag = ((TlvCommon *)buffer)->tag; + tlv->len = ((TlvCommon *)buffer)->len; + tlv->value = (uint8_t *)buffer + TLV_TLV_HEAD_LEN; + *retCode = TLV_OK; + return GetNextTlv(buffer); +} + +static uint8_t *AppendTlv(uint8_t *buffer, const TlvCommon *tlv, const uint8_t *boundary, uint32_t *retCode) +{ + if (buffer > boundary) { + *retCode = TLV_ERR_BUFF_NO_ENOUGH; + return NULL; + } + if (buffer + ((TlvCommon *)tlv)->len + TLV_TLV_HEAD_LEN > boundary) { + *retCode = TLV_ERR_BUFF_NO_ENOUGH; + return NULL; + } + ((TlvCommon *)buffer)->tag = tlv->tag; + ((TlvCommon *)buffer)->len = tlv->len; + if (tlv->len != 0 && tlv->value != NULL) { + if (memcpy_s(buffer + TLV_TLV_HEAD_LEN, boundary - buffer - TLV_TLV_HEAD_LEN, tlv->value, tlv->len) != EOK) { + *retCode = TLV_ERR_BUFF_NO_ENOUGH; + return NULL; + } + } + *retCode = TLV_OK; + return GetNextTlv(buffer); +} + +uint32_t Serialize(const TlvCommon *tlv, uint32_t tlvCount, uint8_t *buff, uint32_t maxBuffSize, uint32_t *buffSize) +{ + if (tlv == NULL || buff == NULL || buffSize == NULL) { + return TLV_ERR_INVALID_PARA; + } + + uint8_t *curr = buff; + uint8_t *boundary = buff + maxBuffSize; + + uint32_t retCode = TLV_OK; + for (uint32_t index = 0; index < tlvCount; index++) { + curr = AppendTlv(curr, &tlv[index], boundary, &retCode); + if (curr == NULL || retCode != TLV_OK) { + return retCode; + } + } + *buffSize = curr - buff; + return TLV_OK; +} + +uint32_t Deserialize(const uint8_t *buff, uint32_t buffSize, TlvCommon *tlv, uint32_t maxTlvCount, uint32_t *tlvCount) +{ + if (buff == NULL || tlv == NULL || tlvCount == NULL) { + return TLV_ERR_INVALID_PARA; + } + + uint8_t *msg = (uint8_t *)buff; + const uint8_t *boundary = buff + buffSize; + uint32_t index = 0; + + while (msg != NULL) { + if (index >= maxTlvCount) { + return TLV_ERR_BUFF_NO_ENOUGH; + } + uint32_t retCode = TLV_OK; + msg = ParseTlv(msg, &tlv[index], boundary, &retCode); + if (msg == NULL || retCode != TLV_OK) { + break; + } + index++; + } + + *tlvCount = index; + return TLV_OK; +} diff --git a/baselib/utils/src/utils_work_queue.c b/baselib/utils/src/utils_work_queue.c new file mode 100644 index 0000000000000000000000000000000000000000..abcc8ec160cfd9bbbaeea1b66ac39ac8f0fdfc8c --- /dev/null +++ b/baselib/utils/src/utils_work_queue.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2021 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 WORKQUEUE_WORK_QUEUE_H +#define WORKQUEUE_WORK_QUEUE_H + +#include "utils_work_queue.h" + +#include + +#include + +#include "utils_list.h" +#include "utils_mem.h" + +#define RUN 0 +#define DIE 1 + +typedef struct WorkQueue { + ListHead head; + pthread_mutex_t mutex; + pthread_cond_t cond; + volatile int32_t state; + uint32_t capacity; + uint32_t size; + pthread_t pthreadId; +} WorkQueue; + +typedef struct { + ListNode linkNode; + WorkProcess process; // callback func + int32_t dataLen; + uint8_t *dataBuff; // user data ptr +} Worker; + +static void *WorkQueueThread(void *data) +{ + WorkQueue *queue = (WorkQueue *)data; + Worker *worker = NULL; + (void)pthread_mutex_lock(&queue->mutex); + while (queue->state == RUN) { + while ((IsEmptyList(&queue->head)) && (queue->state == RUN)) { + pthread_cond_wait(&queue->cond, &queue->mutex); + } + // need to check again + if (queue->state != RUN) { + break; + } + + worker = LIST_ENTRY(queue->head.next, Worker, linkNode); + RemoveListNode(&worker->linkNode); + queue->size--; + + pthread_mutex_unlock(&queue->mutex); + worker->process(worker->dataBuff, worker->dataLen); + FREE(worker); + (void)pthread_mutex_lock(&queue->mutex); + } + + // now the queue is stopped, just remove the nodes. + while (!IsEmptyList(&queue->head)) { + worker = LIST_ENTRY(queue->head.next, Worker, linkNode); + RemoveListNode(&worker->linkNode); + queue->size--; + FREE(worker); + } + + pthread_mutex_unlock(&queue->mutex); + return NULL; +} + +WorkQueue *CreateWorkQueue(uint32_t capacity) +{ + WorkQueue *queue = MALLOC(sizeof(WorkQueue)); + if (queue == NULL) { + return NULL; + } + memset_s(queue, sizeof(WorkQueue), 0, sizeof(WorkQueue)); + + InitListHead(&(queue->head)); + queue->state = RUN; + queue->capacity = capacity; + queue->size = 0; + + int32_t iRet = pthread_mutex_init(&(queue->mutex), NULL); + if (iRet != 0) { + FREE(queue); + return NULL; + } + + iRet = pthread_cond_init(&queue->cond, NULL); + if (iRet != 0) { + (void)pthread_mutex_destroy(&(queue->mutex)); + FREE(queue); + return NULL; + } + + iRet = pthread_create(&queue->pthreadId, NULL, WorkQueueThread, queue); + if (iRet != 0) { + (void)pthread_cond_destroy(&(queue->cond)); + (void)pthread_mutex_destroy(&(queue->mutex)); + FREE(queue); + return NULL; + } + + return queue; +} + +uint32_t DestroyWorkQueue(WorkQueue *queue) +{ + if (queue == NULL) { + return WORK_QUEUE_NULL_PTR; + } + + (void)pthread_mutex_lock(&queue->mutex); + queue->state = DIE; + int32_t iRet = pthread_cond_broadcast(&queue->cond); + if (iRet != 0) { + (void)pthread_mutex_unlock(&queue->mutex); + return WORK_QUEUE_THREAD_COND_ERR; + } + (void)pthread_mutex_unlock(&queue->mutex); + + iRet = pthread_join(queue->pthreadId, NULL); + if (iRet != 0) { + return WORK_QUEUE_THREAD_JOIN_ERR; + } + + FREE(queue); + return WORK_QUEUE_OK; +} + +uint32_t QueueWork(WorkQueue *queue, WorkProcess process, uint8_t *data, uint32_t length) +{ + if ((queue == NULL) || (process == NULL)) { + return WORK_QUEUE_NULL_PTR; + } + if (queue->state != RUN) { + return WORK_QUEUE_STATE_ERR; + } + if (queue->size >= queue->capacity) { + return WORK_QUEUE_FULL; + } + + Worker *worker = MALLOC(sizeof(Worker)); + if (worker == NULL) { + return WORK_QUEUE_MALLOC_ERR; + } + (void)memset_s(worker, sizeof(Worker), 0, sizeof(Worker)); + + InitListHead(&worker->linkNode); + worker->dataLen = length; + worker->dataBuff = data; + worker->process = process; + + (void)pthread_mutex_lock(&queue->mutex); + AddListNodeBefore(&worker->linkNode, &queue->head); + queue->size++; + + (void)pthread_mutex_unlock(&queue->mutex); + (void)pthread_cond_broadcast(&queue->cond); + return WORK_QUEUE_OK; +} +#endif diff --git a/bundle.json b/bundle.json new file mode 100644 index 0000000000000000000000000000000000000000..dd6f460a6a9ac1261914e845646db8d8251de107 --- /dev/null +++ b/bundle.json @@ -0,0 +1,57 @@ +{ + "name": "@openharmony/devicesecuritylevel", + "version": "3.0.0", + "description": "openharmony's device security level management", + "publishAs": "code-segment", + "scripts": { + "install": "DEST_PATH=${DEP_BUNDLE_BASE}/base/security/devicesecuritylevel && mkdir -p $DEST_PATH && cp -r ./* $DEST_PATH" + }, + "author": {}, + "repository": "", + "license": "Apache License 2.0", + "component": { + "name": "devicesecuritylevel", + "subsystem": "security", + "adapted_system_type": [ + "standard" + ], + "deps": { + "components": [ + "device_auth", + "dsoftbus", + "huks", + "ipc_core", + "libhilog", + "samgr_proxy", + "system_ability_fwk", + "utils_base" + ], + "third_party": [ + "boringssl", + "cJSON" + ] + }, + "build": { + "sub_component": [ + "//base/security/devicesecuritylevel/interfaces:dslm_sdk", + "//base/security/devicesecuritylevel/oem_property/ohos:dslm_service", + "//base/security/devicesecuritylevel/profile:dslm_service.rc" + ], + "inner_kits": [ + { + "name": "//base/security/devicesecuritylevel/interfaces:dslm_sdk", + "header": { + "header_files": [ + "device_security_info.h", + "device_security_defines.h" + ], + "header_base": "//base/security/devicesecuritylevel/interfaces/include" + } + } + ], + "test": [ + "//base/security/devicesecuritylevel/test:dslm_test" + ] + } + } +} \ No newline at end of file diff --git a/common/include/dslm_cred.h b/common/include/dslm_cred.h new file mode 100644 index 0000000000000000000000000000000000000000..8b6493fa824323c9a26bd064095ef1972a62cb3f --- /dev/null +++ b/common/include/dslm_cred.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 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 DSLM_CRED_H +#define DSLM_CRED_H + +#include +#include + +#include "device_security_defines.h" + +#define CRED_INFO_VERSION_LEN 32 +#define CRED_INFO_TYPE_LEN 32 +#define CRED_INFO_SIGNTIME_LEN 32 +#define CRED_INFO_UDID_LEN 80 +#define CRED_INFO_MANU_LEN 64 +#define CRED_INFO_MODEL_LEN 64 +#define CRED_INFO_BRAND_LEN 64 +#define CRED_INFO_LEVEL_LEN 16 +#define CRED_INFO_SOFTVERSION_LEN 64 + +typedef enum { + CRED_TYPE_MINI = 100, + CRED_TYPE_SMALL = 200, + CRED_TYPE_STANDARD = 300, + CRED_TYPE_LARGE = 400, +} CredType; + +typedef struct DslmCredInfo { + char version[CRED_INFO_VERSION_LEN]; // the cred version + char type[CRED_INFO_TYPE_LEN]; // debug or release + char signTime[CRED_INFO_SIGNTIME_LEN]; + char udid[CRED_INFO_UDID_LEN]; + char manufacture[CRED_INFO_MANU_LEN]; + char model[CRED_INFO_MODEL_LEN]; + char brand[CRED_INFO_BRAND_LEN]; + char securityLevel[CRED_INFO_LEVEL_LEN]; + char softwareVersion[CRED_INFO_SOFTVERSION_LEN]; + CredType credType; // the parsed and validated type value, assigned only after verification. + uint32_t credLevel; // the parsed level value, assigned only after verification. +} DslmCredInfo; + +#define MAX_CRED_ARRAY_SIZE 48 +typedef struct RequestObject { + uint32_t version; + uint64_t challenge; + uint32_t arraySize; + CredType credArray[MAX_CRED_ARRAY_SIZE]; +} RequestObject; + +typedef struct DslmCredBuff { + CredType type; + uint32_t credLen; + uint8_t *credVal; +} DslmCredBuff; + +typedef int32_t InitDslmCredFunc(DslmCredInfo *credInfo); + +typedef int32_t RequestDslmCredFunc(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff); +typedef int32_t VerifyDslmCredFunc(const DeviceIdentify *device, uint64_t challenge, const DslmCredBuff *credBuff, + DslmCredInfo *credInfo); + +typedef struct ProcessDslmCredFunctions { + InitDslmCredFunc *initFunc; + RequestDslmCredFunc *requestFunc; + VerifyDslmCredFunc *verifyFunc; + uint32_t credTypeCnt; + CredType credTypeArray[MAX_CRED_ARRAY_SIZE]; +} ProcessDslmCredFunctions; + +#ifdef __cplusplus +extern "C" { +#endif + +bool InitDslmCredentialFunctions(const ProcessDslmCredFunctions *func); + +DslmCredBuff *CreateDslmCred(CredType type, uint32_t len, uint8_t *value); + +void DestroyDslmCred(DslmCredBuff *credBuff); + +#ifdef __cplusplus +} +#endif +#endif // DSLM_CRED_H diff --git a/common/include/idevice_security_level.h b/common/include/idevice_security_level.h new file mode 100644 index 0000000000000000000000000000000000000000..c490e8fd3fcf0317e1aeb5190d7b388424390631 --- /dev/null +++ b/common/include/idevice_security_level.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 I_DEVICE_SECURITY_LEVEL_H +#define I_DEVICE_SECURITY_LEVEL_H + +#include +#include + +#include "iremote_broker.h" +#include "message_parcel.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { + +constexpr int32_t SA_ID_DEVICE_SECURITY_MANAGER_SERVICE = 3511; + +class IDeviceSecurityLevel : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Security.DeviceSecurityLevel"); + enum { + CMD_GET_DEVICE_SECURITY_LEVEL = 1, + }; +}; + +class IDeviceSecurityLevelCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.Security.DeviceSecurityLevel.Callback"); + enum { + CMD_SET_DEVICE_SECURITY_LEVEL = 1, + }; +}; + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // I_DEVICE_SECURITY_LEVEL_H diff --git a/docs/cred.md b/docs/cred.md new file mode 100644 index 0000000000000000000000000000000000000000..b2b5bba0ace6e071d42de844b08469637652c6c2 --- /dev/null +++ b/docs/cred.md @@ -0,0 +1,140 @@ +凭据为4段BASE64编码的字符串,中间用"."链接,示例如下: + +``.``.``.`` + + +构造方案如下: + +##### 1. 构造header + +当前header为固定json字符串,如下 + + ``` json + { + "typ": "DSL", + } + ``` + +将header进行BASE64编码,得到``: + +`ewogICAgInR5cCI6ICJEU0wiLAp9` + +##### 2. 构造payload + +根据设备实际情况构造payload的json字符串,示例如下: +``` json +{ + "version":"1.0", + "type":"release", + "signTime":"20210831214343", + "udid":"0070976B63B834FC65E7BBE648155C6D9DD..", + "manufacture":"OHOS", + "model":"NOH-AL00", + "brand":"PHONE", + "securityLevel":"SL1", + "softwareVersion":"2.0.0.165" +} +``` +将payload进行BASE64编码,得到``: + +`ewkJCQkJCQoJInZlcnNpb24iOiIxLjAiLAkJCQkKCSJ0eXBlIjoicmVsZWFzZSIsCQkKCSJzaWduVEltZSI6IjIwMjEwODMxMjE0MzQzIiwKCSJ1ZGlkIjoiMDA3MDk3NkI2M0I4MzRGQzY1RTdCQkU2NDgxNTVDNkQ5REQuLiIsCgkibWFudWZhY3R1cmUiOiJIVUFXRUkiLAoJIm1vZGVsIjoiTk9ILUFMMDAiLAoJImJyYW5kIjoiSFVBV0VJIiwKCSJzZWN1cml0eUxldmVsIjoiU0wxIiwKCSJzb2Z0d2FyZVZlcnNpb24iOiIyLjAuMC4xNjUiCn0=` + +##### 3. 构造signature + +###### 3.1 构建待签名的原始数据 + +将BASE64编码后的header和payload合并,中间用符号"."连接,得到``.`` + +示例如下: + +`ewogICAgInR5cCI6ICJEU0wiLAp9`.`ewkJCQkJCQoJInZlcnNpb24iOiIxLjAiLAkJCQkKCSJ0eXBlIjoicmVsZWFzZSIsCQkKCSJzaWduVEltZSI6IjIwMjEwODMxMjE0MzQzIiwKCSJ1ZGlkIjoiMDA3MDk3NkI2M0I4MzRGQzY1RTdCQkU2NDgxNTVDNkQ5REQuLiIsCgkibWFudWZhY3R1cmUiOiJIVUFXRUkiLAoJIm1vZGVsIjoiTk9ILUFMMDAiLAoJImJyYW5kIjoiSFVBV0VJIiwKCSJzZWN1cml0eUxldmVsIjoiU0wxIiwKCSJzb2Z0d2FyZVZlcnNpb24iOiIyLjAuMC4xNjUiCn0=` + +###### 3.2 生成签名私钥 + +**本流程需要在安全可靠的环境中执行,以确保用于签名的密钥不被泄露** + +使用ECC签名算法对原始数据进行签名,生成签名用ECDSA密钥对:``和`` + +###### 3.3 对原始数据进行签名 + +将``.``作为参数,使用刚刚生成的ECC私钥``对其进行签名,并对签名结果进行BASE64编码,得到返回值`` + +示例如下: + +`e+PKCRQB1RDzOZz9hipnxe32lgufLRTDml1mt3vLNvmS3hgRgstK86ucRjJXIOfdJYi459hg82be61i6p3DkWg==` + +##### 4. 构造attestation info + +**本流程需要在安全可靠的环境中执行,以确保用于签名的密钥不被泄露** + +**attestation info涉及到的各密钥对不需要每次都重复生成,在确保密钥安全的前提下,后续可以直接复用。** + +###### 4.1 生成三级签名验证信息 + +1. 首先生成二级签名用ECDSA密钥对:``和`` + +2. 使用`` 对3.2章节生成的``进行签名,得到`` + +3. 将``和``组合成json字符串示例如下: + + ``` json +{ + "userPublicKey": "", + "signature": "" +} + ``` + +###### 4.2 生成二级签名验证信息 + +1. 生成一级签名用ECDSA密钥对:``和`` +2. 使用`` 对4.1章节生成的``进行签名,得到`` +3. 将``和``组合成json字符串示例如下: + ``` json +{ + "userPublicKey": "", + "signature": "" +} + ``` + +###### 4.3 生成根签名验证信息 + +1. 使用`` 对4.2章节生成的``进行签名(即自签名),得到`` +2. 将``和``组合成json字符串示例如下: + ``` json +{ + "userPublicKey": "", + "signature": "" +} + ``` +###### 4.4 生成合并上述的签名验证信息 +1. 将上述三组签名信息合并到一个json数组中: + ```json +[ + { + "userPublicKey": "", + "signature": "" + }, + { + "userPublicKey": "", + "signature": "" + }, + { + "userPublicKey": "", + "signature": "" + } + ] + ``` +2.对该数据进行base64编码,得到`` + + +示例如下: + `W3sidXNlclB1YmxpY0tleSI6Ik1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWFnOFZIMzN4OUpDOTYwSWsxejNKNmo1cnk0OVJENGt0TTBvQUZGenhiNHdOdS1OckZSbm5XbnZmR3hGTW16VFBMLWYxY1NqWGd2UV9NdU9aenVpclNnIiwiYWxnb3JpdGhtIjoiU0hBMzg0d2l0aEVDRFNBIiwic2lnbmF0dXJlIjoiTUdVQ01DakdwWEZPNlRjb2NtWFdMdHU1SXQ0LVRJNzFoNzhLdDYyYjZ6Mm9tcnNVWElHcnFsMTZXT0ExV2ZfdDdGSU1RZ0l4QVBHMlV5T2d0dk1pbi1hbVR6Wi1DN2ZyMWttVl9jODc4ckFnZVlrUGFxWWdPWWpiSGN0QnFzMkJCV05LMGsxTnJRIn0seyJ1c2VyUHVibGljS2V5IjoiTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVvM0N1Q0VMQzdTaUxhSkNCQ0RkY0NwZXRnSUdraFpMc0ZfYTBkZFUxQ1I3dzU0emppc0NYWkdfdXk2ZGtGZWZrZTNVMW9CaWw0eGk1OU5xeVpOZ1FQbEFISVVHeWtRcVl4cHg1WjBqQUJCSnlBSlVscHRxM0p1Wk5UQTdIOVVLNyIsImFsZ29yaXRobSI6IlNIQTM4NHdpdGhFQ0RTQSIsInNpZ25hdHVyZSI6Ik1HVUNNQ1ZXUWIxdXFLb1E5SUFMaWJiWUlUX1NWSENXem84akcwRG1WNGt6Q0JNQ3pRQU0xZEFaSERGWFdidGUyY0FfWXdJeEFJSXVmaXJHbnN3NlBEV0txRm1mQmQ5Y3BubEFyLXVXV0RqZ2xuenoyRmx2LXNkaVhYRnR3amo3Y1hUTF9FNmJRUSJ9LHsidXNlclB1YmxpY0tleSI6Ik1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFU09kcnY3eXhEaFoxWmRUdDB3QUxCMnhYc0ZsUGV2TkQ0b1lfWE44QWtFTVllWVVyTXBkX1hTQTdlTHo5eVJaa08yX3RoSEx4bUpURGZrOUJFeTlTa0xxUF9xOGZJdzBhSXNBMHI0SlN0djh4YVo0RWxVTGxPV2QxXzF4YV9fdnIiLCJhbGdvcml0aG0iOiJTSEEzODR3aXRoRUNEU0EiLCJzaWduYXR1cmUiOiJNR1FDTURmODNSNktLdm9tZnZyZVYycHhVSEpXb3RwM3BVOUdBWU5tcU1XUmVGcGp6WHpOVjc5dHNrZTBaa21JTVh3TXNBSXdXNUFiOWk4SnlObEp0WDJZcnpaYzJna3RranZ0U2JiSnYwaWhuUmdxMWNjUHBrVDJOc3F4ekJrZkRqOGhQWllzIn1d` + +##### 5. 构造完整的凭据 + +用符号"."连接上述 ``.``.``.`` + +最终结果示例如下: + +`ewogICAgInR5cCI6ICJEU0wiLAp9`.`ewkJCQkJCQoJInZlcnNpb24iOiIxLjAiLAkJCQkKCSJ0eXBlIjoicmVsZWFzZSIsCQkKCSJzaWduVEltZSI6IjIwMjEwODMxMjE0MzQzIiwKCSJ1ZGlkIjoiMDA3MDk3NkI2M0I4MzRGQzY1RTdCQkU2NDgxNTVDNkQ5REQuLiIsCgkibWFudWZhY3R1cmUiOiJIVUFXRUkiLAoJIm1vZGVsIjoiTk9ILUFMMDAiLAoJImJyYW5kIjoiSFVBV0VJIiwKCSJzZWN1cml0eUxldmVsIjoiU0wxIiwKCSJzb2Z0d2FyZVZlcnNpb24iOiIyLjAuMC4xNjUiCn0=`.`e+PKCRQB1RDzOZz9hipnxe32lgufLRTDml1mt3vLNvmS3hgRgstK86ucRjJXIOfdJYi459hg82be61i6p3DkWg==`.`W3sidXNlclB1YmxpY0tleSI6Ik1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWFnOFZIMzN4OUpDOTYwSWsxejNKNmo1cnk0OVJENGt0TTBvQUZGenhiNHdOdS1OckZSbm5XbnZmR3hGTW16VFBMLWYxY1NqWGd2UV9NdU9aenVpclNnIiwiYWxnb3JpdGhtIjoiU0hBMzg0d2l0aEVDRFNBIiwic2lnbmF0dXJlIjoiTUdVQ01DakdwWEZPNlRjb2NtWFdMdHU1SXQ0LVRJNzFoNzhLdDYyYjZ6Mm9tcnNVWElHcnFsMTZXT0ExV2ZfdDdGSU1RZ0l4QVBHMlV5T2d0dk1pbi1hbVR6Wi1DN2ZyMWttVl9jODc4ckFnZVlrUGFxWWdPWWpiSGN0QnFzMkJCV05LMGsxTnJRIn0seyJ1c2VyUHVibGljS2V5IjoiTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVvM0N1Q0VMQzdTaUxhSkNCQ0RkY0NwZXRnSUdraFpMc0ZfYTBkZFUxQ1I3dzU0emppc0NYWkdfdXk2ZGtGZWZrZTNVMW9CaWw0eGk1OU5xeVpOZ1FQbEFISVVHeWtRcVl4cHg1WjBqQUJCSnlBSlVscHRxM0p1Wk5UQTdIOVVLNyIsImFsZ29yaXRobSI6IlNIQTM4NHdpdGhFQ0RTQSIsInNpZ25hdHVyZSI6Ik1HVUNNQ1ZXUWIxdXFLb1E5SUFMaWJiWUlUX1NWSENXem84akcwRG1WNGt6Q0JNQ3pRQU0xZEFaSERGWFdidGUyY0FfWXdJeEFJSXVmaXJHbnN3NlBEV0txRm1mQmQ5Y3BubEFyLXVXV0RqZ2xuenoyRmx2LXNkaVhYRnR3amo3Y1hUTF9FNmJRUSJ9LHsidXNlclB1YmxpY0tleSI6Ik1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFU09kcnY3eXhEaFoxWmRUdDB3QUxCMnhYc0ZsUGV2TkQ0b1lfWE44QWtFTVllWVVyTXBkX1hTQTdlTHo5eVJaa08yX3RoSEx4bUpURGZrOUJFeTlTa0xxUF9xOGZJdzBhSXNBMHI0SlN0djh4YVo0RWxVTGxPV2QxXzF4YV9fdnIiLCJhbGdvcml0aG0iOiJTSEEzODR3aXRoRUNEU0EiLCJzaWduYXR1cmUiOiJNR1FDTURmODNSNktLdm9tZnZyZVYycHhVSEpXb3RwM3BVOUdBWU5tcU1XUmVGcGp6WHpOVjc5dHNrZTBaa21JTVh3TXNBSXdXNUFiOWk4SnlObEp0WDJZcnpaYzJna3RranZ0U2JiSnYwaWhuUmdxMWNjUHBrVDJOc3F4ekJrZkRqOGhQWllzIn1d` + diff --git a/interfaces/BUILD.gn b/interfaces/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..10a7dda05f33de6998216e11899a6aa87090bf36 --- /dev/null +++ b/interfaces/BUILD.gn @@ -0,0 +1,58 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +config("devicesecuritylevel_sdk_config") { + include_dirs = [ "include" ] +} + +ohos_shared_library("dslm_sdk") { + sources = [ + "src/standard/device_security_info.cpp", + "src/standard/device_security_level_callback_helper.cpp", + "src/standard/device_security_level_callback_stub.cpp", + "src/standard/device_security_level_proxy.cpp", + ] + + include_dirs = [ + "//base/security/devicesecuritylevel/service/include", + "//base/security/devicesecuritylevel/common/include", + ] + + public_configs = [ ":devicesecuritylevel_sdk_config" ] + + deps = [] + + external_deps = [ + "ipc:ipc_core", + "utils_base:utils", + ] + + if (is_standard_system) { + external_deps += [ + "hilog_native:libhilog", + "samgr_standard:samgr_proxy", + ] + } + + if (is_large_system) { + external_deps += [ + "hilog:libhilog", + "samgr:samgr_proxy", + ] + } + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/interfaces/include/device_security_defines.h b/interfaces/include/device_security_defines.h new file mode 100644 index 0000000000000000000000000000000000000000..6e55f4ffcd9ab0b789cbe2850a773b1ed462b025 --- /dev/null +++ b/interfaces/include/device_security_defines.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_DEFINES_H +#define DEVICE_SECURITY_DEFINES_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEVICE_ID_MAX_LEN 64 + +typedef struct DeviceIdentify { + uint32_t length; + uint8_t identity[DEVICE_ID_MAX_LEN]; +} DeviceIdentify; + +typedef struct RequestOption { + uint64_t challenge; + uint32_t timeout; + uint32_t extra; +} RequestOption; + +/** + * The error code is synchronized with that in the JAVA, the JAVA code needs to be modified if C code changed. + * An error code can be added only at the end of the list. + */ +enum { + SUCCESS = 0, + ERR_INVALID_PARA = 1, + ERR_INVALID_LEN_PARA = 2, + ERR_NO_MEMORY = 3, + ERR_MEMORY_ERR = 4, + ERR_NO_CHALLENGE = 5, + ERR_NO_CRED = 6, + ERR_SA_BUSY = 7, + ERR_TIMEOUT = 8, + ERR_NOEXIST_REQUEST = 9, + ERR_INVALID_VERSION = 10, + ERR_OEM_ERR = 11, + ERR_HUKS_ERR = 12, + ERR_CHALLENGE_ERR = 13, + ERR_NOT_ONLINE = 14, + ERR_INIT_SELF_ERR = 15, + ERR_JSON_ERR = 16, + ERR_IPC_ERR = 17, + ERR_IPC_REGISTER_ERR = 18, + ERR_IPC_REMOTE_OBJ_ERR = 19, + ERR_IPC_PROXY_ERR = 20, + ERR_IPC_RET_PARCEL_ERR = 21, + ERR_PROXY_REMOTE_ERR = 22, + ERR_MSG_NEIGHBOR_FULL = 23, + ERR_MSG_FULL = 24, + ERR_MSG_ADD_NEIGHBOR = 25, + ERR_MSG_NOT_INIT = 26, + ERR_MSG_CREATE_WORKQUEUE = 27, + ERR_NEED_COMPATIBLE = 28, + ERR_REG_CALLBACK = 29, + ERR_PERMISSION_DENIAL = 30, + ERR_REQUEST_CODE_ERR = 31, + ERR_VERIFY_MODE_CRED_ERR = 32, + ERR_VERIFY_SIGNED_MODE_CRED_ERR = 33, + ERR_VERIFY_MODE_HUKS_ERR = 34, + ERR_PROFILE_CONNECT_ERR = 35, + ERR_MSG_OPEN_SESSION = 36, + ERR_QUERY_WAITING = 37, + ERR_NOEXIST_DEVICE = 38, + ERR_DEFAULT = 0xFFFF +}; + +#ifdef __cplusplus +} +#endif + +#endif // DEVICE_SECURITY_DEFINES_H diff --git a/interfaces/include/device_security_info.h b/interfaces/include/device_security_info.h new file mode 100644 index 0000000000000000000000000000000000000000..e17a7aff046b15622ab5bfd72c38c027d0415293 --- /dev/null +++ b/interfaces/include/device_security_info.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_INFO_H +#define DEVICE_SECURITY_INFO_H + +#include + +#include "device_security_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define DEFAULT_OPTION NULL + +typedef struct DeviceSecurityInfo DeviceSecurityInfo; + +/** + * 设备安全等级等级信息的回调 + */ +typedef void DeviceSecurityInfoCallback(const DeviceIdentify *identify, struct DeviceSecurityInfo *info); + +/** + * 同步请求获取本机/邻居设备的设备安全 + * + * @param [in]identify 设备标识符 + * @param [in]option option值 + * @param [out]info, 需要调用者释放 + * @return + */ +int32_t RequestDeviceSecurityInfo(const DeviceIdentify *identify, const RequestOption *option, + DeviceSecurityInfo **info); + +/** + * 异步请求获取本机/邻居设备的设备安全 + * + * @param [in]identify 设备标识符 + * @param [in]option option值 + * @param [in]callback + * @return + */ +int32_t RequestDeviceSecurityInfoAsync(const DeviceIdentify *identify, const RequestOption *option, + DeviceSecurityInfoCallback callback); + +/** + * 释放设备安全等级信息 + * @param info RequestDeviceSecLevelInfo函数返回的设备安全等级信息 + */ +void FreeDeviceSecurityInfo(DeviceSecurityInfo *info); + +/** + * 提取DeviceSecLevelInfo中的设备安全等级 + * @param info [in]设备安全等级信息 + * @param level [out]设备安全等级。 + * @return + */ +int32_t GetDeviceSecurityLevelValue(const DeviceSecurityInfo *info, int32_t *level); + +#ifdef __cplusplus +} +#endif + +#endif // DEVICE_SECURITY_INFO_H diff --git a/interfaces/src/standard/device_security_info.cpp b/interfaces/src/standard/device_security_info.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f754a864efbb5d568c0796f61f4f701c311377b7 --- /dev/null +++ b/interfaces/src/standard/device_security_info.cpp @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2021 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 "device_security_info.h" + +#include + +#include "hilog/log.h" +#include "iservice_registry.h" + +#include "device_security_level_callback_helper.h" +#include "device_security_level_callback_stub.h" +#include "device_security_level_defines.h" +#include "device_security_level_proxy.h" + +using namespace OHOS::HiviewDFX; +using namespace OHOS::Security::DeviceSecurityLevel; + +int32_t RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify *identify, const RequestOption *option, + ResultCallback callback) +{ + if (identify == NULL || callback == NULL) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo input error."); + return ERR_INVALID_PARA; + } + + constexpr uint32_t DEAFULT_KEEP_LEN = 45; + constexpr uint32_t MAX_KEEP_LEN = 300; + static RequestOption defaultOption = {0, DEAFULT_KEEP_LEN, 0}; + if (option == NULL) { + option = &defaultOption; + } + if (option->timeout > MAX_KEEP_LEN) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo input error, timeout too len."); + return ERR_INVALID_PARA; + } + + auto registry = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (registry == nullptr) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo get registry error."); + return ERR_IPC_REGISTER_ERR; + } + auto object = registry->GetSystemAbility(SA_ID_DEVICE_SECURITY_MANAGER_SERVICE); + if (object == nullptr) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo get object error."); + return ERR_IPC_REMOTE_OBJ_ERR; + } + auto proxy = iface_cast(object); + if (object == nullptr) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo iface_cast error."); + return ERR_IPC_REMOTE_OBJ_ERR; + } + auto &helper = DelayedRefSingleton::GetInstance(); + sptr stub = nullptr; + uint32_t cookie = 0; + + auto result = helper.Publish(*identify, callback, option->timeout, stub, cookie); + if (result == false || stub == nullptr || cookie == 0) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo get stub error."); + return result; + } + + auto success = proxy->RequestDeviceSecurityLevel(*identify, *option, stub->AsObject(), cookie); + if (success != SUCCESS) { + HiLog::Error(LABEL, "GetDeviceSecurityInfo RequestDeviceSecurityLevel error."); + helper.withdraw(cookie); + } + + return success; +} + +int32_t RequestDeviceSecurityInfoImpl(const DeviceIdentify *identify, const RequestOption *option, + DeviceSecurityInfo **info) +{ + std::promise promise; + + auto callback = [&promise](const DeviceIdentify *identify, struct DeviceSecurityInfo *info) { + promise.set_value(info); + return; + }; + auto result = RequestDeviceSecurityInfoAsyncImpl(identify, option, callback); + if (result != SUCCESS) { + HiLog::Error(LABEL, "RequestDeviceSecurityInfoImpl RequestDeviceSecurityLevel error."); + return result; + } + *info = promise.get_future().get(); + return SUCCESS; +} + +void FreeDeviceSecurityInfoImpl(DeviceSecurityInfo *info) +{ + if (info != NULL && info->magicNum == SECURITY_MAGIC) { + delete info; + } +} + +int32_t GetDeviceSecurityLevelValueImpl(const DeviceSecurityInfo *info, int32_t *level) +{ + if (info == NULL || level == nullptr) { + return ERR_INVALID_PARA; + } + if (info->magicNum != SECURITY_MAGIC) { + return ERR_INVALID_PARA; + } + + *level = info->level; + return info->result; +} + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t RequestDeviceSecurityInfo(const DeviceIdentify *identify, const RequestOption *option, + DeviceSecurityInfo **info) +{ + return RequestDeviceSecurityInfoImpl(identify, option, info); +} + +int32_t RequestDeviceSecurityInfoAsync(const DeviceIdentify *identify, const RequestOption *option, + DeviceSecurityInfoCallback callback) +{ + return RequestDeviceSecurityInfoAsyncImpl(identify, option, callback); +} + +void FreeDeviceSecurityInfo(DeviceSecurityInfo *info) +{ + return FreeDeviceSecurityInfoImpl(info); +} + +int32_t GetDeviceSecurityLevelValue(const DeviceSecurityInfo *info, int32_t *level) +{ + return GetDeviceSecurityLevelValueImpl(info, level); +} + +#ifdef __cplusplus +} +#endif diff --git a/interfaces/src/standard/device_security_level_callback_helper.cpp b/interfaces/src/standard/device_security_level_callback_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5e2556c7df996d0bdae99717846079fe8ee641ca --- /dev/null +++ b/interfaces/src/standard/device_security_level_callback_helper.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2021 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 "device_security_level_callback_helper.h" + +#include +#include + +#include "timer.h" + +#include "hilog/log.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS::HiviewDFX; + +constexpr char TIMER_NAME[] = "DSLM_CALL_TIMER"; +constexpr uint32_t KEEP_COMPENSATION_LEN = 5; +constexpr uint32_t MAX_CALLBACKS_NUM = 128; + +DeviceSecurityLevelCallbackHelper::DeviceSecurityLevelCallbackHelper() +{ + auto request = [this](uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { + return this->OnRemoteRequest(code, data, reply, option); + }; + stub_ = new (std::nothrow) DeviceSecurityLevelCallbackStub(request); +} + +DeviceSecurityLevelCallbackHelper::~DeviceSecurityLevelCallbackHelper() +{ + stub_ = nullptr; +} + +bool DeviceSecurityLevelCallbackHelper::Publish(const DeviceIdentify &identity, ResultCallback callback, uint32_t keep, + sptr &stub, uint32_t &cookie) +{ + if (stub_ == nullptr) { + return false; + } + + auto result = holder_.PushCallback(identity, callback, keep, cookie); + if (result == false) { + HiLog::Error(LABEL, "DeviceSecurityLevelCallbackHelper::PushCallback failed"); + return false; + } + + stub = stub_; + return true; +} + +bool DeviceSecurityLevelCallbackHelper::withdraw(uint32_t cookie) +{ + if (cookie == 0) { + return false; + } + + auto result = holder_.PopCallback(cookie); + if (result == false) { + HiLog::Error(LABEL, "DeviceSecurityLevelCallbackHelper::withdraw failed"); + return false; + } + return true; +} + +int32_t DeviceSecurityLevelCallbackHelper::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (DeviceSecurityLevelCallbackStub::GetDescriptor() != data.ReadInterfaceToken()) { + return SUCCESS; + } + + if (code == DeviceSecurityLevelCallbackStub::CMD_SET_DEVICE_SECURITY_LEVEL) { + auto cookie = data.ReadUint32(); + auto result = data.ReadUint32(); + auto level = data.ReadUint32(); + HiLog::Info(LABEL, "cookie %{public}u, result %{public}u, level %{public}u", cookie, result, level); + holder_.PopCallback(cookie, result, level); + } + + return SUCCESS; +} + +DeviceSecurityLevelCallbackHelper::CallbackInfoHolder::CallbackInfoHolder() : timer_(TIMER_NAME) +{ + timer_.Setup(); +} + +DeviceSecurityLevelCallbackHelper::CallbackInfoHolder::~CallbackInfoHolder() +{ + timer_.Shutdown(); +} + +bool DeviceSecurityLevelCallbackHelper::CallbackInfoHolder::PushCallback(const DeviceIdentify &identity, + ResultCallback callback, uint32_t keep, uint32_t &cookie) +{ + std::lock_guard lock(mutex_); + if (map_.size() > MAX_CALLBACKS_NUM) { + HiLog::Error(LABEL, "DeviceSecurityLevelCallbackHelper::PushCallback reached max"); + return false; + } + + cookie = ++generate_; + CallbackInfo info = {.identity = identity, .callback = callback, .cookie = cookie}; + auto result = map_.emplace(generate_, info); + if (result.second) { + auto deleter = [cookie, this]() { PopCallback(cookie, ERR_TIMEOUT, 0); }; + keep += KEEP_COMPENSATION_LEN; + timer_.Register(deleter, keep * 1000, true); // 1000 millsec + } + return result.second; +} + +bool DeviceSecurityLevelCallbackHelper::CallbackInfoHolder::PopCallback(uint32_t cookie, uint32_t result, + uint32_t level) +{ + std::lock_guard lock(mutex_); + auto iter = map_.find(cookie); + if (iter == map_.end()) { + return false; + } + DeviceIdentify identity = iter->second.identity; + ResultCallback callback = iter->second.callback; + map_.erase(iter); + + if (callback != nullptr) { + auto creator = [result, level]() { + DeviceSecurityInfo *info = new (std::nothrow) DeviceSecurityInfo; + if (info != nullptr) { + info->magicNum = SECURITY_MAGIC; + info->result = result; + info->level = level; + } + return info; + }; + callback(&identity, creator()); + } + + return true; +} +bool DeviceSecurityLevelCallbackHelper::CallbackInfoHolder::PopCallback(uint32_t cookie) +{ + std::lock_guard lock(mutex_); + auto iter = map_.find(cookie); + if (iter == map_.end()) { + return false; + } + map_.erase(iter); + return true; +} + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS diff --git a/interfaces/src/standard/device_security_level_callback_helper.h b/interfaces/src/standard/device_security_level_callback_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..39b33dbb4b8ce1910df0b3d97d8df6066e251ca8 --- /dev/null +++ b/interfaces/src/standard/device_security_level_callback_helper.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_LEVEL_CALLBACK_HELPER +#define DEVICE_SECURITY_LEVEL_CALLBACK_HELPER + +#include +#include + +#include "singleton.h" +#include "timer.h" + +#include "device_security_level_callback_stub.h" +#include "device_security_level_defines.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS; + +class DeviceSecurityLevelCallbackHelper { + DECLARE_DELAYED_REF_SINGLETON(DeviceSecurityLevelCallbackHelper); + +public: + bool Publish(const DeviceIdentify &identity, ResultCallback callback, uint32_t keep, + sptr &stub, uint32_t &cookie); + bool withdraw(uint32_t cookie); + +private: + class CallbackInfoHolder { + struct CallbackInfo { + DeviceIdentify identity; + ResultCallback callback; + uint64_t cookie; + }; + + public: + CallbackInfoHolder(); + virtual ~CallbackInfoHolder(); + bool PushCallback(const DeviceIdentify &identity, ResultCallback callback, uint32_t keep, uint32_t &cookie); + bool PopCallback(uint32_t cookie, uint32_t result, uint32_t level); + bool PopCallback(uint32_t cookie); + + private: + std::map map_; + uint32_t generate_ {0}; + std::mutex mutex_; + OHOS::Utils::Timer timer_; + }; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option); + CallbackInfoHolder holder_; + sptr stub_; +}; +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // DEVICE_SECURITY_LEVEL_CALLBACK_HELPER \ No newline at end of file diff --git a/interfaces/src/standard/device_security_level_callback_stub.cpp b/interfaces/src/standard/device_security_level_callback_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c951df67c653725646d8d2934c5dd54d3a678d81 --- /dev/null +++ b/interfaces/src/standard/device_security_level_callback_stub.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 "device_security_level_callback_stub.h" + +#include "hilog/log.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS::HiviewDFX; +DeviceSecurityLevelCallbackStub::DeviceSecurityLevelCallbackStub(RemoteRequest request) : remoteRequest_(request) +{ +} + +int32_t DeviceSecurityLevelCallbackStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + if (remoteRequest_ != nullptr) { + return remoteRequest_(code, data, reply, option); + } + return SUCCESS; +} +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS diff --git a/interfaces/src/standard/device_security_level_callback_stub.h b/interfaces/src/standard/device_security_level_callback_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..bcc1a7fcd925f5488cb314e97c4bdf91a45ff4ac --- /dev/null +++ b/interfaces/src/standard/device_security_level_callback_stub.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_LEVEL_CALLBACK_STUB +#define DEVICE_SECURITY_LEVEL_CALLBACK_STUB + +#include "iremote_stub.h" +#include "nocopyable.h" +#include +#include + +#include "idevice_security_level.h" + +#include "device_security_defines.h" +#include "device_security_level_defines.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS; +class DeviceSecurityLevelCallbackStub : public IRemoteStub { + using RemoteRequest = + std::function; + +public: + DISALLOW_COPY_AND_MOVE(DeviceSecurityLevelCallbackStub); + explicit DeviceSecurityLevelCallbackStub(RemoteRequest request); + virtual ~DeviceSecurityLevelCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + RemoteRequest remoteRequest_; +}; +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // DEVICE_SECURITY_LEVEL_CALLBACK_STUB \ No newline at end of file diff --git a/interfaces/src/standard/device_security_level_defines.h b/interfaces/src/standard/device_security_level_defines.h new file mode 100644 index 0000000000000000000000000000000000000000..e6e052c6c2f54776b3d8d60a5b6959374be54012 --- /dev/null +++ b/interfaces/src/standard/device_security_level_defines.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_LEVEL_DEFINES_H +#define DEVICE_SECURITY_LEVEL_DEFINES_H + +#include + +#include "hilog/log.h" + +#include "device_security_defines.h" +#include "device_security_info.h" + +typedef struct DeviceSecurityInfo { + uint32_t magicNum; + uint32_t result; + uint32_t level; +} DeviceSecurityInfo; + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { + +constexpr uint64_t SECURITY_MAGIC = 0xABCD1234; + +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0xD002F00, "DSLM_SDK"}; + +using ResultCallback = std::function; + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // DEVICE_SECURITY_LEVEL_DEFINES_H diff --git a/interfaces/src/standard/device_security_level_proxy.cpp b/interfaces/src/standard/device_security_level_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..79b6c1c47f6e0fa7cdabb70f444e234656837661 --- /dev/null +++ b/interfaces/src/standard/device_security_level_proxy.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 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 "device_security_level_proxy.h" + +#include "hilog/log.h" + +#include "device_security_level_defines.h" +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS::HiviewDFX; +DeviceSecurityLevelProxy::DeviceSecurityLevelProxy(const sptr &impl) + : IRemoteProxy(impl) +{ +} + +int32_t DeviceSecurityLevelProxy::RequestDeviceSecurityLevel(const DeviceIdentify &identify, + const RequestOption &option, const sptr &callback, uint64_t cookie) +{ + MessageParcel data; + MessageParcel reply; + + auto length = identify.length; + if (length == 0 || length > DEVICE_ID_MAX_LEN) { + HiLog::Error(LABEL, "RequestDeviceSecurityLevel invalid para len."); + return ERR_INVALID_LEN_PARA; + } + + if (!data.WriteInterfaceToken(GetDescriptor())) { + HiLog::Error(LABEL, "RequestDeviceSecurityLevel write descriptor failed"); + return ERR_INVALID_PARA; + } + + /* DeviceIdentify */ + data.WriteUint32(length); + data.WriteBuffer(identify.identity, DEVICE_ID_MAX_LEN); + /* option */ + data.WriteUint64(option.challenge); + data.WriteUint32(option.timeout); + data.WriteUint32(option.extra); + + /* callback */ + data.WriteRemoteObject(callback); + /* cookie */ + data.WriteUint32(cookie); + + MessageOption ipcOption = {MessageOption::TF_SYNC}; + auto result = Remote()->SendRequest(CMD_GET_DEVICE_SECURITY_LEVEL, data, reply, ipcOption); + if (result != ERR_NONE) { + HiLog::Error(LABEL, "RequestDeviceSecurityLevelSendRequest send failed, ret is %{public}d", result); + return result; + } + + if (reply.GetReadableBytes() < sizeof(uint32_t)) { + HiLog::Error(LABEL, "RequestDeviceSecurityLevelSendRequest result length error"); + return ERR_IPC_RET_PARCEL_ERR; + } + + auto status = reply.ReadUint32(); + if (status != cookie) { + HiLog::Error(LABEL, "RequestDeviceSecurityLevelSendRequest result value error, ret is %{public}u", status); + return status; + } + + return SUCCESS; +} + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS diff --git a/interfaces/src/standard/device_security_level_proxy.h b/interfaces/src/standard/device_security_level_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..0786f645d65402f31701199f1ee0a6490544752d --- /dev/null +++ b/interfaces/src/standard/device_security_level_proxy.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021 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 DEVICE_SECURITY_LEVEL_PROXY +#define DEVICE_SECURITY_LEVEL_PROXY + +#include "iremote_proxy.h" +#include "nocopyable.h" + +#include "idevice_security_level.h" + +#include "device_security_defines.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS; +class DeviceSecurityLevelProxy : public IRemoteProxy { +public: + DISALLOW_COPY_AND_MOVE(DeviceSecurityLevelProxy); + explicit DeviceSecurityLevelProxy(const sptr &impl); + virtual ~DeviceSecurityLevelProxy() = default; + int32_t RequestDeviceSecurityLevel(const DeviceIdentify &identify, const RequestOption &option, + const sptr &callback, uint64_t cookie); + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // DEVICE_SECURITY_LEVEL_PROXY \ No newline at end of file diff --git a/oem_property/ohos/BUILD.gn b/oem_property/ohos/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..13a1ca0bf96f7776c8195ba9efd09188c478a34d --- /dev/null +++ b/oem_property/ohos/BUILD.gn @@ -0,0 +1,60 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# sa lib +ohos_shared_library("dslm_service") { + sources = [ "dslm_ohos_credential.c" ] + + include_dirs = [ + "//base/security/devicesecuritylevel/common/include", + "//base/security/devicesecuritylevel/interfaces/include", + ] + + deps = [ + ":dslm_ohos_cread_obj", + "//base/security/devicesecuritylevel/baselib/utils:utils_static", + "//base/security/devicesecuritylevel/service/sa:service_sa_static", + ] + + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} + +ohos_source_set("dslm_ohos_cread_obj") { + sources = [ + "impl/dslm_ohos_request.c", + "impl/dslm_ohos_verify.c", + ] + + include_dirs = [ + "//base/security/devicesecuritylevel/common/include", + "//base/security/devicesecuritylevel/interfaces/include", + ] + + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/oem_property/ohos/dslm_ohos_credential.c b/oem_property/ohos/dslm_ohos_credential.c new file mode 100644 index 0000000000000000000000000000000000000000..09ebfdb6c64c23929f9b6d4278494c707b4905e2 --- /dev/null +++ b/oem_property/ohos/dslm_ohos_credential.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 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 "dslm_ohos_credential.h" + +#include + +#include "utils_log.h" + +__attribute__((constructor)) static void Constructor(void) +{ + const ProcessDslmCredFunctions func = { + .initFunc = NULL, + .requestFunc = RequestOhosDslmCred, + .verifyFunc = VerifyOhosDslmCred, + .credTypeCnt = 1, + .credTypeArray = {CRED_TYPE_STANDARD}, + }; + InitDslmCredentialFunctions(&func); +} \ No newline at end of file diff --git a/oem_property/ohos/dslm_ohos_credential.h b/oem_property/ohos/dslm_ohos_credential.h new file mode 100644 index 0000000000000000000000000000000000000000..78444971bb5b84ddc3b9bbc522d7a4e598437072 --- /dev/null +++ b/oem_property/ohos/dslm_ohos_credential.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 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 DSLM_OHOS_CREDENTIAL_H +#define DSLM_OHOS_CREDENTIAL_H + +#include "impl/dslm_ohos_request.h" +#include "impl/dslm_ohos_verify.h" + +#endif // DSLM_OHOS_CREDENTIAL_H diff --git a/oem_property/ohos/impl/dslm_ohos_request.c b/oem_property/ohos/impl/dslm_ohos_request.c new file mode 100644 index 0000000000000000000000000000000000000000..3a92fd478e13222ca3bfe3be5c330957f930aa66 --- /dev/null +++ b/oem_property/ohos/impl/dslm_ohos_request.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021 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 "dslm_ohos_request.h" + +#include "utils_log.h" +#include +#include + +#include "utils_mem.h" + +int32_t RequestOhosDslmCred(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff) +{ + SECURITY_LOG_INFO("Invoke RequestOhosDslmCred"); + static const char *credStr = + "ewogICAgInR5cCI6ICJEU0wiLAp9." + "eyJzZWN1cml0eUxldmVsIjoiU0w0IiwibWFudWZhY3R1cmUiOiJNQU5VIiwic2lnblRpbWUiOiIyMDIxMTEwOTExMjczNCIsIm1vZGVsIjoiTU" + "9ERU" + "wiLCJ0eXBlIjoiZGVidWciLCJ1ZGlkIjoiMTIzNDU2Nzg5MEFCQ0RFRiIsInZlcnNpb24iOiIxLjAiLCJicmFuZCI6IkJSQU5EIiwic29mdHdh" + "cmVW" + "ZXJzaW9uIjoiMi4xLjAuNDIifQ==.MEUCIQCMglMcuEUhJBwbkPbgNi_VI7ksPkGZXBPMQI_YmepubQIgPuF9WLjaTum9d_" + "KhqmVdjfRmcFbhPh4Laq2NnlVz3uc." + "W3sidXNlclB1YmxpY0tleSI6Ik1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRWFnOFZIMzN4OUpDOTYwSWsxejNKNmo1cnk0OV" + "JENG" + "t0TTBvQUZGenhiNHdOdS1OckZSbm5XbnZmR3hGTW16VFBMLWYxY1NqWGd2UV9NdU9aenVpclNnIiwiYWxnb3JpdGhtIjoiU0hBMzg0d2l0aEVD" + "RFNB" + "Iiwic2lnbmF0dXJlIjoiTUdVQ01DakdwWEZPNlRjb2NtWFdMdHU1SXQ0LVRJNzFoNzhLdDYyYjZ6Mm9tcnNVWElHcnFsMTZXT0ExV2ZfdDdGSU" + "1RZ0" + "l4QVBHMlV5T2d0dk1pbi1hbVR6Wi1DN2ZyMWttVl9jODc4ckFnZVlrUGFxWWdPWWpiSGN0QnFzMkJCV05LMGsxTnJRIn0seyJ1c2VyUHVibGlj" + "S2V5" + "IjoiTUhZd0VBWUhLb1pJemowQ0FRWUZLNEVFQUNJRFlnQUVvM0N1Q0VMQzdTaUxhSkNCQ0RkY0NwZXRnSUdraFpMc0ZfYTBkZFUxQ1I3dzU0em" + "ppc0" + "NYWkdfdXk2ZGtGZWZrZTNVMW9CaWw0eGk1OU5xeVpOZ1FQbEFISVVHeWtRcVl4cHg1WjBqQUJCSnlBSlVscHRxM0p1Wk5UQTdIOVVLNyIsImFs" + "Z29y" + "aXRobSI6IlNIQTM4NHdpdGhFQ0RTQSIsInNpZ25hdHVyZSI6Ik1HVUNNQ1ZXUWIxdXFLb1E5SUFMaWJiWUlUX1NWSENXem84akcwRG1WNGt6Q0" + "JNQ3" + "pRQU0xZEFaSERGWFdidGUyY0FfWXdJeEFJSXVmaXJHbnN3NlBEV0txRm1mQmQ5Y3BubEFyLXVXV0RqZ2xuenoyRmx2LXNkaVhYRnR3amo3Y1hU" + "TF9F" + "NmJRUSJ9LHsidXNlclB1YmxpY0tleSI6Ik1IWXdFQVlIS29aSXpqMENBUVlGSzRFRUFDSURZZ0FFU09kcnY3eXhEaFoxWmRUdDB3QUxCMnhYc0" + "ZsUG" + "V2TkQ0b1lfWE44QWtFTVllWVVyTXBkX1hTQTdlTHo5eVJaa08yX3RoSEx4bUpURGZrOUJFeTlTa0xxUF9xOGZJdzBhSXNBMHI0SlN0djh4YVo0" + "RWxV" + "TGxPV2QxXzF4YV9fdnIiLCJhbGdvcml0aG0iOiJTSEEzODR3aXRoRUNEU0EiLCJzaWduYXR1cmUiOiJNR1FDTURmODNSNktLdm9tZnZyZVYycH" + "hVSE" + "pXb3RwM3BVOUdBWU5tcU1XUmVGcGp6WHpOVjc5dHNrZTBaa21JTVh3TXNBSXdXNUFiOWk4SnlObEp0WDJZcnpaYzJna3RranZ0U2JiSnYwaWhu" + "Umdx" + "MWNjUHBrVDJOc3F4ekJrZkRqOGhQWllzIn1d"; + + DslmCredBuff *out = CreateDslmCred(CRED_TYPE_STANDARD, strlen(credStr) + 1, (uint8_t *)credStr); + if (out == NULL) { + return ERR_MEMORY_ERR; + } + *credBuff = out; + return SUCCESS; +} diff --git a/oem_property/ohos/impl/dslm_ohos_request.h b/oem_property/ohos/impl/dslm_ohos_request.h new file mode 100644 index 0000000000000000000000000000000000000000..a3511fa0d656f16ed8a08417d1af4bcbd563f6bd --- /dev/null +++ b/oem_property/ohos/impl/dslm_ohos_request.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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 DSLM_OHOS_REQUEST_H +#define DSLM_OHOS_REQUEST_H + +#include + +#include "device_security_defines.h" +#include "dslm_cred.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t RequestOhosDslmCred(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_OHOS_REQUEST_H diff --git a/oem_property/ohos/impl/dslm_ohos_verify.c b/oem_property/ohos/impl/dslm_ohos_verify.c new file mode 100644 index 0000000000000000000000000000000000000000..1f231ecd73047796795de6ed829a7a7db4f71618 --- /dev/null +++ b/oem_property/ohos/impl/dslm_ohos_verify.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 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 "dslm_ohos_verify.h" + +#include "utils_log.h" +#include +#include + +#include "utils_mem.h" + +#define OHOS_DEFAULT_LEVEL 1 +int32_t VerifyOhosDslmCred(const DeviceIdentify *device, uint64_t challenge, const DslmCredBuff *credBuff, + DslmCredInfo *credInfo) +{ + SECURITY_LOG_INFO("Invoke VerifyOhosDslmCred = %{public}s", (char *)credBuff->credVal); + credInfo->credLevel = OHOS_DEFAULT_LEVEL; + return 0; +} \ No newline at end of file diff --git a/oem_property/ohos/impl/dslm_ohos_verify.h b/oem_property/ohos/impl/dslm_ohos_verify.h new file mode 100644 index 0000000000000000000000000000000000000000..bc5d54e67c3793cdb84d8fb81c172e17bd03d46c --- /dev/null +++ b/oem_property/ohos/impl/dslm_ohos_verify.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021 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 DSLM_OHOS_VERIFY_H +#define DSLM_OHOS_VERIFY_H + +#include + +#include "device_security_defines.h" +#include "dslm_cred.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t VerifyOhosDslmCred(const DeviceIdentify *device, uint64_t challenge, const DslmCredBuff *credBuff, + DslmCredInfo *credInfo); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_OHOS_VERIFY_H diff --git a/profile/BUILD.gn b/profile/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..afa70d081aa5d9dca7137371df98d245873780cd --- /dev/null +++ b/profile/BUILD.gn @@ -0,0 +1,32 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +ohos_sa_profile("devicesecuritylevel_profile") { + sources = [ "dslm_service.xml" ] + part_name = "devicesecuritylevel" +} + +ohos_prebuilt_etc("dslm_service.rc") { + if (use_musl) { + source = "dslm_service.cfg" + } else { + source = "dslm_service.rc" + } + + deps = [ ":devicesecuritylevel_profile" ] + relative_install_dir = "init" + subsystem_name = "security" + part_name = "devicesecuritylevel" +} diff --git a/profile/dslm_service.cfg b/profile/dslm_service.cfg new file mode 100644 index 0000000000000000000000000000000000000000..600cc289e269f1209880ce0c1d7c7a2c14b2a35e --- /dev/null +++ b/profile/dslm_service.cfg @@ -0,0 +1,16 @@ +{ + "jobs" : [{ + "name" : "post-fs-data", + "cmds" : [ + "start dslm_service" + ] + } + ], + "services" : [{ + "name" : "dslm_service", + "path" : ["/system/bin/sa_main", "/system/profile/dslm_service.xml"], + "uid" : "system", + "gid" : ["system", "shell"] + } + ] +} \ No newline at end of file diff --git a/profile/dslm_service.rc b/profile/dslm_service.rc new file mode 100644 index 0000000000000000000000000000000000000000..a0984c2ea6c6279c951233d55716315db2ecaa79 --- /dev/null +++ b/profile/dslm_service.rc @@ -0,0 +1,21 @@ +# Copyright (C) 2021 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. + +on post-fs-data + start dslm_service + +service dslm_service /system/bin/sa_main /system/profile/dslm_service.xml + class z_core + user system + group system shell + seclabel u:r:dslm_service:s0 \ No newline at end of file diff --git a/profile/dslm_service.xml b/profile/dslm_service.xml new file mode 100644 index 0000000000000000000000000000000000000000..a4967966defe2fb50ee4efe6de7c88d14e6a9863 --- /dev/null +++ b/profile/dslm_service.xml @@ -0,0 +1,29 @@ + + + + dslm_service + + 3511 + libdslm_service.z.so + 4700 + + true + false + 1 + + + + diff --git a/service/bigdata/BUILD.gn b/service/bigdata/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..33b1aa84461cd1a374dee059f13cf83ecd3d111f --- /dev/null +++ b/service/bigdata/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# service_bigdata object +ohos_source_set("service_bigdata_obj") { + sources = [ "dslm_bigdata.cpp" ] + + include_dirs = [ "//base/security/devicesecuritylevel/service/include" ] + + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/service/bigdata/dslm_bigdata.cpp b/service/bigdata/dslm_bigdata.cpp new file mode 100644 index 0000000000000000000000000000000000000000..16f68cefcbaeed590a90aba6cd0b97735de40aa2 --- /dev/null +++ b/service/bigdata/dslm_bigdata.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "dslm_bigdata.h" + +#ifdef __cplusplus +extern "C" { +#endif +__attribute__((weak)) void ReportAppInvokeEvent(const AppInvokeEvent *event) +{ + return; +} + +__attribute__((weak)) void ReportSecurityInfoSyncEvent(const SecurityInfoSyncEvent *event) +{ + return; +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/service/common/BUILD.gn b/service/common/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1d78e91a5c3e0a5a3f8fdef0592387cfe343423d --- /dev/null +++ b/service/common/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# service_common object +ohos_source_set("service_common_obj") { + sources = [ + "dslm_crypto.c", + "dslm_msg_serialize.c", + ] + + include_dirs = [ + "//base/security/devicesecuritylevel/interfaces/include", + "//base/security/devicesecuritylevel/service/include", + ] + + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + if (is_standard_system) { + deps += [ "//third_party/boringssl:crypto" ] + } + + external_deps = [ + "hilog_native:libhilog", + "ipc:ipc_core", + "utils_base:utils", + ] + + if (is_large_system) { + aosp_deps = [ "shared_library:libcrypto" ] + } + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/service/common/dslm_crypto.c b/service/common/dslm_crypto.c new file mode 100644 index 0000000000000000000000000000000000000000..491d5da14104487597044e5bc23579447a24819b --- /dev/null +++ b/service/common/dslm_crypto.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 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 "dslm_crypto.h" + +#include + +void GenerateRandom(RandomValue *rand, uint32_t length) +{ + if (rand == NULL) { + return; + } + rand->length = (length > RAMDOM_MAX_LEN) ? RAMDOM_MAX_LEN : length; + + RAND_bytes(&rand->value[0], rand->length); +} \ No newline at end of file diff --git a/service/common/dslm_msg_serialize.c b/service/common/dslm_msg_serialize.c new file mode 100644 index 0000000000000000000000000000000000000000..f704589989b0a099e63d7b72e471b3d08c0c30e8 --- /dev/null +++ b/service/common/dslm_msg_serialize.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021 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 "dslm_msg_serialize.h" + +#include +#include +#include + +#include "utils_json.h" +#include "utils_log.h" +#include "utils_mem.h" + +static inline bool IsAscii(const uint8_t ch) +{ + return (((ch) & (~0x7f)) == 0); +} + +bool CheckMessage(const uint8_t *msg, uint32_t length) +{ + // our msgs is a printable string + if (msg[length - 1] != '\0') { + return false; + } + for (uint32_t i = 0; i < length - 1; i++) { + if (!IsAscii(msg[i])) { + return false; + } + } + return true; +} + +MessagePacket *ParseMessage(const MessageBuff *buff) +{ + if (!CheckMessage(buff->buff, buff->length)) { + SECURITY_LOG_DEBUG("ERR MSG"); + return NULL; + } + + JsonHandle handle = CreateJson((const char *)buff->buff); + if (handle == NULL) { + SECURITY_LOG_DEBUG("ERR JSON MSG"); + return NULL; + } + + char *payload = NULL; + MessagePacket *packet = NULL; + do { + int32_t msgType = GetJsonFieldInt(handle, FIELD_MESSAGE); + if (msgType < 0) { + break; + } + payload = ConvertJsonToString(GetJsonFieldJson(handle, FIELD_PAYLOAD)); + if (payload == NULL) { + break; + } + packet = MALLOC(sizeof(MessagePacket)); + if (packet == NULL) { + free(payload); + break; + } + packet->type = msgType; + packet->payload = (uint8_t *)payload; + packet->length = strlen(payload) + 1; // for the end flag '\0' + } while (0); + + DestroyJson(handle); + return packet; +} + +MessageBuff *SerializeMessage(const MessagePacket *packet) +{ + if (!CheckMessage(packet->payload, packet->length)) { + SECURITY_LOG_DEBUG("ERR MSG"); + return NULL; + } + + MessageBuff *out = MALLOC(sizeof(MessageBuff)); + if (out == NULL) { + return NULL; + } + memset_s(out, sizeof(MessageBuff), 0, sizeof(MessageBuff)); + + JsonHandle json = CreateJson(NULL); + if (json == NULL) { + FREE(out); + return NULL; + } + + AddFieldIntToJson(json, FIELD_MESSAGE, packet->type); + AddFieldStringToJson(json, FIELD_PAYLOAD, (const char *)packet->payload); + + out->buff = (uint8_t *)ConvertJsonToString(json); + if (out->buff == NULL) { + FREE(out); + DestroyJson(json); + return NULL; + } + out->length = strlen((char *)out->buff) + 1; + DestroyJson(json); + return out; +} + +void FreeMessagePacket(MessagePacket *packet) +{ + if (packet == NULL) { + return; + } + if (packet->payload != NULL) { + FREE(packet->payload); + packet->payload = NULL; + } + FREE((void *)packet); +} + +void FreeMessageBuff(MessageBuff *buff) +{ + if (buff == NULL) { + return; + } + if (buff->buff != NULL) { + FREE(buff->buff); + buff->buff = NULL; + } + FREE((void *)buff); +} diff --git a/service/dslm/BUILD.gn b/service/dslm/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..b1d3ccf200557c451865768de210e4ef2ce9a5ee --- /dev/null +++ b/service/dslm/BUILD.gn @@ -0,0 +1,66 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +service_dslm_sources = [ + "dslm_core_process.c", + "dslm_credential.c", + "dslm_device_list.c", + "dslm_fsm_process.c", + "dslm_hidumper.c", + "dslm_hievent.c", + "dslm_inner_process.c", + "dslm_msg_utils.c", +] + +service_dslm_include_dirs = [ + "//base/security/devicesecuritylevel/common/include", + "//base/security/devicesecuritylevel/interfaces/include", + "//base/security/devicesecuritylevel/service/include", +] + +# service_dslm object +ohos_source_set("service_dslm_obj") { + sources = service_dslm_sources + include_dirs = service_dslm_include_dirs + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + defines = [ + "MAX_SEND_TIMES=5", + "SEND_MSG_TIMEOUT_LEN=40000", + ] + part_name = "devicesecuritylevel" + subsystem_name = "security" +} + +# service_dslm object, only for test +ohos_source_set("service_dslm_test_obj") { + testonly = true + sources = service_dslm_sources + include_dirs = service_dslm_include_dirs + deps = [ "//base/security/devicesecuritylevel/baselib/utils:utils_static" ] + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + defines = [ + "MAX_SEND_TIMES=5", + "SEND_MSG_TIMEOUT_LEN=500", + ] + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/service/dslm/dslm_core_defines.h b/service/dslm/dslm_core_defines.h new file mode 100644 index 0000000000000000000000000000000000000000..1ea769b3b5f1b7527778fb96eafc6943278935e3 --- /dev/null +++ b/service/dslm/dslm_core_defines.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 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 DSLM_CORE_DEFINES_H +#define DSLM_CORE_DEFINES_H + +#include +#include + +#include "utils_list.h" +#include "utils_mutex.h" +#include "utils_state_machine.h" +#include "utils_timer.h" + +#include "device_security_defines.h" +#include "dslm_cred.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define VERSION_MAJOR 3 +#define VERSION_MINOR 0 +#define VERSION_PATCH 0 + +typedef struct DslmDeviceInfo { + ListNode linkNode; + StateMachine machine; + Mutex mutex; + DeviceIdentify identity; + uint32_t version; + uint32_t onlineStatus; + uint32_t deviceType; + uint64_t nonce; + uint64_t nonceTimeStamp; + uint64_t lastOnlineTime; + uint64_t lastOfflineTime; + uint64_t lastRequestTime; + uint64_t lastResponseTime; + uint64_t transNum; + TimerHandle timeHandle; + uint32_t queryTimes; + uint32_t result; + DslmCredInfo credInfo; + ListHead notifyList; +} DslmDeviceInfo; + +static inline uint32_t GetCurrentVersion() +{ + // shift major 16 bit, shift minor 8 bit + return (VERSION_MAJOR << 16) + (VERSION_MINOR << 8) + VERSION_PATCH; +} + +static inline uint8_t VersionToMajor(uint32_t version) +{ + // shift 16 bit to get version first 8 bit data as the main version + return (version & 0xFF0000) >> 16; +} + +static inline uint8_t VersionToMinor(uint32_t version) +{ + // get version middle 8 bit data as the minor version + return (version & 0xFF00) >> 8; +} + +static inline uint8_t VersionToPatch(uint32_t version) +{ + // get version last 8 bit data as the patch version + return version & 0xFF; +} + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_CORE_DEFINES_H diff --git a/service/dslm/dslm_core_process.c b/service/dslm/dslm_core_process.c new file mode 100644 index 0000000000000000000000000000000000000000..085080b24e3ec0a59827e2ddd5411572d85114bb --- /dev/null +++ b/service/dslm/dslm_core_process.c @@ -0,0 +1,263 @@ +/* + * Copyright (c) 2021 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 "dslm_core_process.h" + +#include +#include + +#include "utils_datetime.h" +#include "utils_log.h" +#include "utils_mem.h" +#include "utils_timer.h" + +#include "dslm_credential.h" +#include "dslm_device_list.h" +#include "dslm_fsm_process.h" +#include "dslm_hievent.h" +#include "dslm_messenger_wrapper.h" +#include "dslm_msg_utils.h" +#include "dslm_notify_node.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId); + +int32_t OnPeerMsgRequestInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len) +{ + if (deviceId == NULL || msg == NULL || len == 0) { + return ERR_INVALID_PARA; + } + + SECURITY_LOG_DEBUG("OnPeerMsgRequestInfoReceived msg is %s", (char *)msg); + MessageBuff buff = {.length = len, .buff = (uint8_t *)msg}; + + RequestObject reqObject; + memset_s(&reqObject, sizeof(RequestObject), 0, sizeof(RequestObject)); + + // Parse the msg + int32_t ret = ParseDeviceSecInfoRequest(&buff, &reqObject); + if (ret != SUCCESS) { + return ret; + } + + // process + DslmCredBuff *cred = NULL; + ret = DefaultRequestDslmCred(deviceId, &reqObject, &cred); + if (ret != SUCCESS) { + return ret; + } + + // build and send response + MessageBuff *resBuff = NULL; + ret = BuildDeviceSecInfoResponse(reqObject.challenge, cred, &resBuff); + if (ret == SUCCESS) { + SendMsgToDevice(0, deviceId, resBuff->buff, resBuff->length); + FreeMessageBuff(resBuff); + } + DestroyDslmCred(cred); + + return SUCCESS; +} + +int32_t OnPeerMsgResponseInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len) +{ + if (deviceId == NULL || msg == NULL || len == 0) { + return ERR_INVALID_PARA; + } + SECURITY_LOG_DEBUG("OnPeerMsgResponseInfoReceived msg is %s", (char *)msg); + + // find the device; + DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId); + if (deviceInfo == NULL) { + SECURITY_LOG_ERROR("OnPeerMsgResponseInfoReceived no existed device"); + return ERR_NOEXIST_DEVICE; + } + + MessageBuff buff = { + .length = len, + .buff = (uint8_t *)msg, + }; + + ScheduleDslmStateMachine(deviceInfo, EVENT_CRED_RSP, &buff); + ReportHiEventInfoSync(deviceInfo); + return SUCCESS; +} + +int32_t OnMsgSendResultNotifier(const DeviceIdentify *deviceId, uint64_t transNo, uint32_t result) +{ + SECURITY_LOG_INFO("OnMsgSendResultNotifier msg trans is %{public}u result %{public}u", (uint32_t)transNo, result); + + if (result == SUCCESS) { + return SUCCESS; + } + + DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(deviceId); + if (deviceInfo == NULL) { + return SUCCESS; + } + + SECURITY_LOG_INFO("current DslmDeviceInfo transNum is %{public}u", (uint32_t)deviceInfo->transNum); + if (deviceInfo->transNum != transNo) { + return SUCCESS; + } + + if (deviceInfo->credInfo.credLevel != 0) { + return SUCCESS; + } + + ScheduleDslmStateMachine(deviceInfo, EVENT_MSG_SEND_FAILED, &result); + + return SUCCESS; +} + +int32_t OnRequestDeviceSecLevelInfo(const DeviceIdentify *deviceId, const RequestOption *option, uint32_t cookie, + RequestCallback callback) +{ + if (deviceId == NULL || option == NULL || callback == NULL) { + SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo invalid para"); + return ERR_INVALID_PARA; + } + + if (GetMessengerStatus() != true) { + SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo softbus service not startup complete"); + return ERR_MSG_NOT_INIT; + } + + const DeviceIdentify *curr = RefreshDeviceOnlineStatus(deviceId); + + DslmDeviceInfo *deviceInfo = GetDslmDeviceInfo(curr); + if (deviceInfo == NULL) { + SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo input device not exist"); + return ERR_NOEXIST_DEVICE; + } + + ReportHiEventAppInvoke(deviceInfo); + + if (deviceInfo->onlineStatus != ONLINE_STATUS_ONLINE) { + SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo input device not online"); + return ERR_NOT_ONLINE; + } + DslmNotifyListNode *nofityNode = MALLOC(sizeof(DslmNotifyListNode)); + if (nofityNode == NULL) { + SECURITY_LOG_ERROR("OnRequestDeviceSecLevelInfo malloc error"); + return ERR_NO_MEMORY; + } + nofityNode->cookie = cookie; + nofityNode->requestCallback = callback; + nofityNode->start = GetMillisecondSinceBoot(); + nofityNode->keep = option->timeout * 1000; // 1000 ms per second + ScheduleDslmStateMachine(deviceInfo, EVENT_SDK_GET, nofityNode); + return SUCCESS; +} + +int32_t OnPeerStatusReceiver(const DeviceIdentify *deviceId, uint32_t status, uint32_t devType) +{ + DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(deviceId); + if (info == NULL) { + return SUCCESS; + } + + if (info->onlineStatus == status) { + return SUCCESS; + } + + uint32_t event = (status == ONLINE_STATUS_ONLINE) ? EVENT_DEVICE_ONLINE : EVENT_DEVICE_OFFLINE; + ScheduleDslmStateMachine(info, event, &devType); + return SUCCESS; +} + +bool InitSelfDeviceSecureLevel() +{ + uint32_t devType = 0; + const DeviceIdentify *device = GetSelfDevice(&devType); + if (device->length == 0) { + SECURITY_LOG_ERROR("InitDeviceSecLevel, GetSelfDevice failed"); + return false; + } + + DslmDeviceInfo *info = CreatOrGetDslmDeviceInfo(device); + if (info == NULL) { + SECURITY_LOG_ERROR("InitDeviceSecLevel, CreatOrGetDslmDeviceInfo failed"); + return false; + } + + info->deviceType = devType; + + if (info->credInfo.credLevel > 0) { + info->result = SUCCESS; + return true; + } + + DefaultInitDslmCred(&info->credInfo); + + int ret = OnPeerStatusReceiver(device, ONLINE_STATUS_ONLINE, devType); + if (ret != SUCCESS) { + SECURITY_LOG_ERROR("InitDeviceSecLevel, make self online failed"); + } + return true; +} + +bool InitDslmProcess() +{ + static bool isInited = false; + static Mutex initMutex = INITED_MUTEX; + + if (GetMessengerStatus() == false) { + return false; + } + + if (isInited == true) { + return true; + } + + LockMutex(&initMutex); + bool result = InitSelfDeviceSecureLevel(); + if (result) { + isInited = true; + } + UnlockMutex(&initMutex); + return isInited; +} + +bool DeinitDslmProcess() +{ + return true; +} + +static const DeviceIdentify *RefreshDeviceOnlineStatus(const DeviceIdentify *deviceId) +{ + uint32_t devType = 0; + if (deviceId == NULL) { + return NULL; + } + + if (deviceId->identity[0] == 0) { + SECURITY_LOG_INFO("RefreshDeviceOnlineStatus to self"); + return GetSelfDevice(&devType); + } + + if (GetPeerDeviceOnlineStatus(deviceId, &devType)) { + OnPeerStatusReceiver(deviceId, ONLINE_STATUS_ONLINE, devType); + } + + return deviceId; +} + +#ifdef __cplusplus +} +#endif diff --git a/service/dslm/dslm_credential.c b/service/dslm/dslm_credential.c new file mode 100644 index 0000000000000000000000000000000000000000..e07ba4943d409922d542abf092dc87c244edde87 --- /dev/null +++ b/service/dslm/dslm_credential.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2021 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 "dslm_credential.h" + +#include +#include +#include + +#include "securec.h" + +#include "utils_log.h" +#include "utils_mem.h" + +static inline ProcessDslmCredFunctions *GetFunctionCb() +{ + static ProcessDslmCredFunctions cb = {NULL, NULL, NULL, 0, {0}}; + return &cb; +} + +bool InitDslmCredentialFunctions(const ProcessDslmCredFunctions *funcs) +{ + if (funcs == NULL) { + return false; + } + ProcessDslmCredFunctions *cb = GetFunctionCb(); + memcpy_s(cb, sizeof(ProcessDslmCredFunctions), funcs, sizeof(ProcessDslmCredFunctions)); + SECURITY_LOG_INFO("InitDslmCredentialFunctions success"); + return true; +} + +int32_t DefaultRequestDslmCred(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff) +{ + ProcessDslmCredFunctions *cb = GetFunctionCb(); + RequestDslmCredFunc *request = cb->requestFunc; + if (request != NULL) { + return request(device, obj, credBuff); + } + SECURITY_LOG_INFO("invoke DefaultRequestDslmCred"); + return -1; +} + +int32_t DefaultVerifyDslmCred(const DeviceIdentify *device, uint64_t challenge, const DslmCredBuff *credBuff, + DslmCredInfo *credInfo) +{ + ProcessDslmCredFunctions *cb = GetFunctionCb(); + VerifyDslmCredFunc *verify = cb->verifyFunc; + if (verify != NULL) { + return verify(device, challenge, credBuff, credInfo); + } + SECURITY_LOG_INFO("invoke DefaultVerifyDslmCred"); + return -1; +} + +int32_t DefaultInitDslmCred(DslmCredInfo *credInfo) +{ + ProcessDslmCredFunctions *cb = GetFunctionCb(); + InitDslmCredFunc *init = cb->initFunc; + if (init != NULL) { + return init(credInfo); + } + SECURITY_LOG_INFO("invoke DefaultInitDslmCred"); + return -1; +} + +int32_t GetSupportedCredTypes(CredType *list, uint32_t len) +{ + if ((list == NULL) || len == 0) { + return 0; + } + ProcessDslmCredFunctions *cb = GetFunctionCb(); + uint32_t outLen = len; + if (len > cb->credTypeCnt) { + outLen = cb->credTypeCnt; + } + for (uint32_t i = 0; i < outLen; i++) { + *(list + i) = cb->credTypeArray[i]; + } + return outLen; +} + +DslmCredBuff *CreateDslmCred(CredType type, uint32_t len, uint8_t *value) +{ + if ((len == 0) || (value == NULL)) { + return NULL; + } + DslmCredBuff *outBuff = (DslmCredBuff *)MALLOC(sizeof(DslmCredBuff)); + if (outBuff == NULL) { + return NULL; + } + uint8_t *outValue = (uint8_t *)MALLOC(len); + if (outValue == NULL) { + FREE(outBuff); + return NULL; + } + memset_s(outValue, len, 0, len); + if (memcpy_s(outValue, len, value, len) != EOK) { + FREE(outBuff); + FREE(outValue); + return NULL; + } + outBuff->credVal = outValue; + outBuff->type = type; + outBuff->credLen = len; + return outBuff; +} + +void DestroyDslmCred(DslmCredBuff *credBuff) +{ + if (credBuff == NULL) { + return; + } + if (credBuff->credVal != NULL) { + FREE(credBuff->credVal); + credBuff->credVal = NULL; + } + FREE(credBuff); +} \ No newline at end of file diff --git a/service/dslm/dslm_credential.h b/service/dslm/dslm_credential.h new file mode 100644 index 0000000000000000000000000000000000000000..cca963425af7fb5bb5a6e8cf5279fa628586063b --- /dev/null +++ b/service/dslm/dslm_credential.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 DSLM_CREDENTIAL_H +#define DSLM_CREDENTIAL_H + +#include + +#include "dslm_cred.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t DefaultRequestDslmCred(const DeviceIdentify *device, const RequestObject *obj, DslmCredBuff **credBuff); + +int32_t DefaultVerifyDslmCred(const DeviceIdentify *device, uint64_t challenge, const DslmCredBuff *credBuff, + DslmCredInfo *credInfo); + +int32_t DefaultInitDslmCred(DslmCredInfo *credInfo); + +int32_t GetSupportedCredTypes(CredType *list, uint32_t len); + +#ifdef __cplusplus +} +#endif +#endif // DSLM_CREDENTIAL_H diff --git a/service/dslm/dslm_device_list.c b/service/dslm/dslm_device_list.c new file mode 100644 index 0000000000000000000000000000000000000000..0ae4f3bd6f8ae12e8e2edf90d5516384628e0a6d --- /dev/null +++ b/service/dslm/dslm_device_list.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2021 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 "dslm_device_list.h" + +#include +#include + +#include "utils_datetime.h" +#include "utils_list.h" +#include "utils_log.h" +#include "utils_mem.h" +#include "utils_mutex.h" + +#include "device_security_defines.h" +#include "dslm_core_defines.h" +#include "dslm_fsm_process.h" + +#define MAX_DEVICE_CNT 128 + +static inline Mutex *GetDeviceListMutex() +{ + static Mutex mutex = INITED_MUTEX; + return &mutex; +} + +static ListHead *GetDeviceList() +{ + static ListHead list = INIT_LIST(list); + return &list; +} + +static int32_t GetDeviceListSize() +{ + int32_t size = 0; + ListNode *node = NULL; + + LockMutex(GetDeviceListMutex()); + FOREACH_LIST_NODE (node, GetDeviceList()) { + size++; + } + UnlockMutex(GetDeviceListMutex()); + return size; +} + +DslmDeviceInfo *GetDslmDeviceInfo(const DeviceIdentify *device) +{ + if (device == NULL) { + return NULL; + } + + DslmDeviceInfo *result = NULL; + ListNode *node = NULL; + + LockMutex(GetDeviceListMutex()); + FOREACH_LIST_NODE (node, GetDeviceList()) { + DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode); + if (IsSameDevice(&info->identity, device)) { + result = info; + break; + } + } + UnlockMutex(GetDeviceListMutex()); + return result; +} + +DslmDeviceInfo *CreatOrGetDslmDeviceInfo(const DeviceIdentify *device) +{ + if (device == NULL) { + return NULL; + } + + if (device->length != DEVICE_ID_MAX_LEN) { + return NULL; + } + + DslmDeviceInfo *info = GetDslmDeviceInfo(device); + if (info != NULL) { + return info; + } + + if (GetDeviceListSize() > MAX_DEVICE_CNT) { + return NULL; + } + + info = MALLOC(sizeof(DslmDeviceInfo)); + if (info == NULL) { + return NULL; + } + memset_s(info, sizeof(DslmDeviceInfo), 0, sizeof(DslmDeviceInfo)); + + if (memcpy_s(&info->identity, sizeof(DeviceIdentify), device, sizeof(DeviceIdentify)) != EOK) { + FREE(info); + return NULL; + } + InitDslmStateMachine(info); + LockMutex(GetDeviceListMutex()); + AddListNode(&info->linkNode, GetDeviceList()); + InitListHead(&info->notifyList); + UnlockMutex(GetDeviceListMutex()); + return info; +} + +bool IsSameDevice(const DeviceIdentify *first, const DeviceIdentify *second) +{ + if ((first == NULL) || (second == NULL)) { + return false; + } + if (first->length != second->length) { + return false; + } + if (memcmp(first->identity, second->identity, first->length) != 0) { + return false; + } + return true; +} + +void ForEachDeviceDump(const ProcessDumpFunction dumper, int32_t dumpHandle) +{ + ListNode *node = NULL; + if (dumper == NULL) { + return; + } + + LockMutex(GetDeviceListMutex()); + FOREACH_LIST_NODE (node, GetDeviceList()) { + const DslmDeviceInfo *info = LIST_ENTRY(node, DslmDeviceInfo, linkNode); + dumper(info, dumpHandle); + } + UnlockMutex(GetDeviceListMutex()); +} diff --git a/service/dslm/dslm_device_list.h b/service/dslm/dslm_device_list.h new file mode 100644 index 0000000000000000000000000000000000000000..3a23f16268441d85093175a15ecade25285b0f54 --- /dev/null +++ b/service/dslm/dslm_device_list.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 DSLM_DEVICE_LIST_H +#define DSLM_DEVICE_LIST_H + +#include +#include + +#include "device_security_defines.h" +#include "dslm_core_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ONLINE_STATUS_ONLINE 1 +#define ONLINE_STATUS_OFFLINE 0 + +typedef void (*ProcessDumpFunction)(const DslmDeviceInfo *info, int32_t dumpHandle); + +DslmDeviceInfo *CreatOrGetDslmDeviceInfo(const DeviceIdentify *device); + +DslmDeviceInfo *GetDslmDeviceInfo(const DeviceIdentify *device); + +bool IsSameDevice(const DeviceIdentify *first, const DeviceIdentify *second); + +void ForEachDeviceDump(const ProcessDumpFunction dumper, int32_t dumpHandle); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_DEVICE_LIST_H diff --git a/service/dslm/dslm_fsm_process.c b/service/dslm/dslm_fsm_process.c new file mode 100644 index 0000000000000000000000000000000000000000..9c5aee54cee860ca9e52e8119a0b1a6d2322c2fa --- /dev/null +++ b/service/dslm/dslm_fsm_process.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2021 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 "dslm_fsm_process.h" + +#include + +#include "utils_datetime.h" +#include "utils_hexstring.h" +#include "utils_log.h" +#include "utils_mem.h" +#include "utils_state_machine.h" +#include "utils_timer.h" + +#include "dslm_device_list.h" +#include "dslm_inner_process.h" +#include "dslm_notify_node.h" + +typedef bool DslmInfoChecker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo, + uint32_t *result); + +static bool SdkTimeoutCheker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo, + uint32_t *result); +static bool RequestDoneCheker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo, + uint32_t *result); + +static uint32_t GenerateMachineId(const DeviceIdentify *identity); +static bool CheckTimesAndSendCredRequest(DslmDeviceInfo *info, bool enforce); +static void StopSendDeviceInfoRequestTimer(DslmDeviceInfo *info); +static void ProcessSendDeviceInfoCallback(DslmDeviceInfo *info, DslmInfoChecker checker); + +static void TimerProcessSendDeviceInfoRequestTimeOut(const void *context); +static void TimerProcessSdkRequestTimeout(const void *context); + +static bool ProcessDeviceOnline(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessSendCredRequest(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessSdkRequest(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessSendRequestFailed(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessDeviceOffline(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessVerifyCredMessage(const StateMachine *machine, uint32_t event, const void *para); +static bool ProcessSdkTimeout(const StateMachine *machine, uint32_t event, const void *para); + +static uint32_t GenerateMachineId(const DeviceIdentify *identity) +{ +#define MASK_LOW 0x00ff +#define MACHINE_ID_LENGTH 4 +#define SHIFT_LENGTH 8 +#define MASK_HIGH 0xff00 + uint16_t machineId = 0; + HexStringToByte((const char *)identity->identity, MACHINE_ID_LENGTH, (uint8_t *)&machineId, sizeof(machineId)); + return ((machineId & MASK_HIGH) >> SHIFT_LENGTH) | ((machineId & MASK_LOW) << SHIFT_LENGTH); +} + +static void TimerProcessSendDeviceInfoRequestTimeOut(const void *context) +{ + if (context == NULL) { + return; + } + // the context info will nerver be freed, so feel free use it. + ScheduleDslmStateMachine((DslmDeviceInfo *)context, EVENT_TIME_OUT, NULL); +} + +static void TimerProcessSdkRequestTimeout(const void *context) +{ + if (context == NULL) { + return; + } + // the context info will nerver be freed, so feel free use it. + ScheduleDslmStateMachine((DslmDeviceInfo *)context, EVENT_SDK_TIMEOUT, NULL); +} + +static void StopSendDeviceInfoRequestTimer(DslmDeviceInfo *info) +{ + if (info->timeHandle != 0) { + StopTimerTask(info->timeHandle); + info->timeHandle = 0; + } +} + +static void StartSendDeviceInfoRequestTimer(DslmDeviceInfo *info) +{ + info->timeHandle = StartOnceTimerTask(SEND_MSG_TIMEOUT_LEN, TimerProcessSendDeviceInfoRequestTimeOut, info); +} + +static bool CheckTimesAndSendCredRequest(DslmDeviceInfo *info, bool enforce) +{ +#ifndef MAX_SEND_TIMES +#define MAX_SEND_TIMES 5 +#endif + +#ifndef SEND_MSG_TIMEOUT_LEN +#define SEND_MSG_TIMEOUT_LEN 40000 +#endif + + if (!enforce && info->queryTimes > MAX_SEND_TIMES) { + return false; + } + + CheckAndGenerateChallenge(info); + SendDeviceInfoRequest(info); + info->queryTimes++; + info->lastRequestTime = GetMillisecondSinceBoot(); + StopSendDeviceInfoRequestTimer(info); + StartSendDeviceInfoRequestTimer(info); + return true; +} + +static void ProcessSendDeviceInfoCallback(DslmDeviceInfo *info, DslmInfoChecker checker) +{ + if (info == NULL || checker == NULL) { + return; + } + ListNode *node = NULL; + ListNode *temp = NULL; + + FOREACH_LIST_NODE_SAFE (node, &info->notifyList, temp) { + DslmNotifyListNode *notifyNode = LIST_ENTRY(node, DslmNotifyListNode, linkNode); + uint32_t result; + DslmCallbackInfo cbInfo; + bool check = checker(info, notifyNode, &cbInfo, &result); + if (!check) { + continue; + } + SECURITY_LOG_DEBUG("ProcessSendDeviceInfoCallback result %{public}u for device %{public}x, level %{public}u.", + result, info->machine.machineId, cbInfo.level); + notifyNode->requestCallback(notifyNode->cookie, result, &cbInfo); + RemoveListNode(node); + FREE(notifyNode); + } +} + +static bool ProcessDeviceOnline(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + if (para != NULL) { + info->deviceType = *(uint32_t *)para; + } + info->onlineStatus = ONLINE_STATUS_ONLINE; + info->queryTimes = 0; + info->lastOnlineTime = GetMillisecondSinceBoot(); + return ProcessSendCredRequest(machine, event, para); +} + +static bool ProcessSendCredRequest(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + bool enforce = (para != NULL); + return CheckTimesAndSendCredRequest(info, enforce); +} + +static bool ProcessSdkRequest(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *deviceInfo = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + DslmNotifyListNode *notify = (DslmNotifyListNode *)para; + if (notify == NULL) { + return false; + } + + if (notify->cookie == 0 || notify->requestCallback == NULL) { + SECURITY_LOG_ERROR("ProcessSdkRequest invalied cookie or callback."); + FREE(notify); + return false; + } + + AddListNode(¬ify->linkNode, &deviceInfo->notifyList); + SECURITY_LOG_DEBUG("ProcessSdkRequest, device is %{public}x, cookie is %{public}u, keep is %{public}u", + deviceInfo->machine.machineId, notify->cookie, notify->keep); + uint32_t state = GetCurrentMachineState(deviceInfo); + if (state == STATE_SUCCESS || state == STATE_FAILED || deviceInfo->credInfo.credLevel != 0) { + ProcessSendDeviceInfoCallback(deviceInfo, RequestDoneCheker); + return true; + } + + StartOnceTimerTask(notify->keep, TimerProcessSdkRequestTimeout, deviceInfo); + return true; +} + +static bool ProcessSendRequestFailed(const StateMachine *machine, uint32_t event, const void *para) +{ +#define ERR_SESSION_OPEN_FAILED 2 + DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + if (para == NULL) { + return false; + } + + uint32_t reason = *(uint32_t *)para; + info->result = reason; + if (reason == ERR_SESSION_OPEN_FAILED) { + info->result = ERR_MSG_OPEN_SESSION; + StopSendDeviceInfoRequestTimer(info); + ProcessSendDeviceInfoCallback(info, RequestDoneCheker); + return false; + } + + return CheckTimesAndSendCredRequest(info, false); +} + +static bool ProcessDeviceOffline(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + info->onlineStatus = ONLINE_STATUS_OFFLINE; + info->queryTimes = 0; + info->lastOfflineTime = GetMillisecondSinceBoot(); + StopSendDeviceInfoRequestTimer(info); + return true; +} + +static bool ProcessVerifyCredMessage(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *deviceInfo = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + MessageBuff *buff = (MessageBuff *)para; + + deviceInfo->lastResponseTime = GetMillisecondSinceBoot(); + + deviceInfo->result = VerifyDeviceInfoResponse(deviceInfo, buff); + ProcessSendDeviceInfoCallback(deviceInfo, RequestDoneCheker); + + if (deviceInfo->result == SUCCESS) { + SECURITY_LOG_INFO("ProcessVerifyCredMessage success, level is %{public}u", deviceInfo->credInfo.credLevel); + StopSendDeviceInfoRequestTimer(deviceInfo); + return true; + } + + CheckTimesAndSendCredRequest(deviceInfo, false); + return false; +} + +static bool ProcessSdkTimeout(const StateMachine *machine, uint32_t event, const void *para) +{ + DslmDeviceInfo *info = STATE_MACHINE_ENTRY(machine, DslmDeviceInfo, machine); + ProcessSendDeviceInfoCallback(info, SdkTimeoutCheker); + return true; +} + +static bool SdkTimeoutCheker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo, + uint32_t *result) +{ + uint64_t curr = GetMillisecondSinceBoot(); + if (node->start + node->keep > curr) { + return false; + } + *result = ERR_TIMEOUT; + cbInfo->level = 0; + cbInfo->extraLen = 0; + cbInfo->extraBuff = NULL; + return true; +} + +static bool RequestDoneCheker(const DslmDeviceInfo *devInfo, const DslmNotifyListNode *node, DslmCallbackInfo *cbInfo, + uint32_t *result) +{ + *result = devInfo->result; + cbInfo->level = devInfo->credInfo.credLevel; + cbInfo->extraLen = 0; + cbInfo->extraBuff = NULL; + return true; +} + +void InitDslmStateMachine(DslmDeviceInfo *info) +{ + if (info == NULL) { + return; + } + uint32_t machineId = GenerateMachineId(&info->identity); + InitStateMachine(&info->machine, machineId, STATE_INIT); + SECURITY_LOG_INFO("InitDslmStateMachine success, machineId is %{public}x", machineId); +} + +void ScheduleDslmStateMachine(DslmDeviceInfo *info, uint32_t event, const void *para) +{ + if (info == NULL) { + return; + } + + static const StateNode stateNodes[] = { + {STATE_INIT, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED}, + {STATE_INIT, EVENT_SDK_GET, ProcessSdkRequest, STATE_INIT, STATE_INIT}, + {STATE_WAITING_CRED_RSP, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED}, + {STATE_WAITING_CRED_RSP, EVENT_CRED_RSP, ProcessVerifyCredMessage, STATE_SUCCESS, STATE_FAILED}, + {STATE_WAITING_CRED_RSP, EVENT_MSG_SEND_FAILED, ProcessSendRequestFailed, STATE_WAITING_CRED_RSP, STATE_FAILED}, + {STATE_WAITING_CRED_RSP, EVENT_TIME_OUT, ProcessSendCredRequest, STATE_WAITING_CRED_RSP, STATE_FAILED}, + {STATE_WAITING_CRED_RSP, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT}, + {STATE_WAITING_CRED_RSP, EVENT_SDK_GET, ProcessSdkRequest, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP}, + {STATE_WAITING_CRED_RSP, EVENT_SDK_TIMEOUT, ProcessSdkTimeout, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP}, + {STATE_SUCCESS, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT}, + {STATE_SUCCESS, EVENT_SDK_GET, ProcessSdkRequest, STATE_SUCCESS, STATE_SUCCESS}, + {STATE_FAILED, EVENT_DEVICE_ONLINE, ProcessDeviceOnline, STATE_WAITING_CRED_RSP, STATE_FAILED}, + {STATE_FAILED, EVENT_CRED_RSP, ProcessVerifyCredMessage, STATE_SUCCESS, STATE_FAILED}, + {STATE_FAILED, EVENT_DEVICE_OFFLINE, ProcessDeviceOffline, STATE_INIT, STATE_INIT}, + {STATE_FAILED, EVENT_CHECK, ProcessSendCredRequest, STATE_WAITING_CRED_RSP, STATE_WAITING_CRED_RSP}, + {STATE_FAILED, EVENT_SDK_GET, ProcessSdkRequest, STATE_FAILED, STATE_FAILED}, + {STATE_FAILED, EVENT_SDK_TIMEOUT, ProcessSdkTimeout, STATE_FAILED, STATE_FAILED}, + }; + + static const uint32_t nodeCnt = sizeof(stateNodes) / sizeof(StateNode); + + ScheduleMachine(stateNodes, nodeCnt, &info->machine, event, para); +} + +uint32_t GetCurrentMachineState(const DslmDeviceInfo *info) +{ + if (info == NULL) { + return STATE_FAILED; + } + return info->machine.currState; +} \ No newline at end of file diff --git a/service/dslm/dslm_fsm_process.h b/service/dslm/dslm_fsm_process.h new file mode 100644 index 0000000000000000000000000000000000000000..f074ccaa0484b194312091f31728faaa1aa625d1 --- /dev/null +++ b/service/dslm/dslm_fsm_process.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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 DSLM_FSM_PROCESS_H +#define DSLM_FSM_PROCESS_H + +#include + +#include "dslm_core_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// item state +enum { + STATE_INIT = 0, + STATE_WAITING_CRED_RSP = 1, + STATE_SUCCESS = 2, + STATE_FAILED = 3, +}; + +// item event +enum { + EVENT_DEVICE_ONLINE = 0, + EVENT_CRED_RSP = 1, + EVENT_MSG_SEND_FAILED = 2, + EVENT_DEVICE_OFFLINE = 3, + EVENT_TIME_OUT = 4, + EVENT_SDK_GET = 5, + EVENT_SDK_TIMEOUT = 6, + EVENT_CHECK = 7, +}; + +void InitDslmStateMachine(DslmDeviceInfo *info); +void ScheduleDslmStateMachine(DslmDeviceInfo *info, uint32_t event, const void *para); +uint32_t GetCurrentMachineState(const DslmDeviceInfo *info); +#ifdef __cplusplus +} +#endif +#endif // DSLM_FSM_PROCESS_H diff --git a/service/dslm/dslm_hidumper.c b/service/dslm/dslm_hidumper.c new file mode 100644 index 0000000000000000000000000000000000000000..c7e201d9fbc61ba5fad2cddb42cd4acc1a90ffa7 --- /dev/null +++ b/service/dslm/dslm_hidumper.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2021 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 "dslm_hidumper.h" + +#include + +#include "securec.h" + +static void PrintBanner(int fd) +{ + dprintf(fd, " ___ ___ _ __ __ ___ _ _ __ __ ___ ___ ___ \n"); + dprintf(fd, " | \\/ __| | | \\/ | | \\| | | | \\/ | _ \\ __| _ \\\n"); + dprintf(fd, " | |) \\__ \\ |__| |\\/| | | |) | |_| | |\\/| | _/ _|| /\n"); + dprintf(fd, " |___/|___/____|_| |_| |___/ \\___/|_| |_|_| |___|_|_\\\n"); +} + +void DslmDumper(int fd) +{ + PrintBanner(fd); +} \ No newline at end of file diff --git a/service/dslm/dslm_hievent.c b/service/dslm/dslm_hievent.c new file mode 100644 index 0000000000000000000000000000000000000000..d8c6e1e5aef2a81882df4930cd9f39351f061f1b --- /dev/null +++ b/service/dslm/dslm_hievent.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021 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 "dslm_hievent.h" + +#include + +#include "dslm_bigdata.h" + +void ReportHiEventInfoSync(const DslmDeviceInfo *info) +{ + if (info == NULL) { + return; + } + if (!ReportSecurityInfoSyncEvent) { + return; + } + SecurityInfoSyncEvent event; + memset_s(&event, sizeof(SecurityInfoSyncEvent), 0, sizeof(SecurityInfoSyncEvent)); + + if (info->lastResponseTime >= info->lastRequestTime) { + event.costTime = info->lastResponseTime - info->lastRequestTime; + } + + event.retCode = info->result; + event.secLevel = info->credInfo.credLevel; + event.localVersion = GetCurrentVersion(); + event.targetVersion = info->version; + if (memcpy_s(event.targetModel, MODEL_MAX_LEN, info->credInfo.model, CRED_INFO_MODEL_LEN) != EOK) { + memset_s(event.targetModel, MODEL_MAX_LEN, 0, MODEL_MAX_LEN); + } + + event.credType = info->credInfo.credType; + ReportSecurityInfoSyncEvent(&event); +} + +void ReportHiEventAppInvoke(const DslmDeviceInfo *info) +{ + if (info == NULL) { + return; + } + + if (!ReportAppInvokeEvent) { + return; + } + AppInvokeEvent event; + memset_s(&event, sizeof(AppInvokeEvent), 0, sizeof(AppInvokeEvent)); + event.costTime = 0; + if (info->lastResponseTime >= info->lastRequestTime) { + event.costTime = info->lastResponseTime - info->lastRequestTime; + } + event.uid = 0; + event.retCode = info->result; + event.secLevel = info->credInfo.credLevel; + event.retMode = (info->result == ERR_NEED_COMPATIBLE) ? 1 : 0; + + if (memcpy_s(event.targetModel, MODEL_MAX_LEN, info->credInfo.model, CRED_INFO_MODEL_LEN) != EOK) { + memset_s(event.targetModel, MODEL_MAX_LEN, 0, MODEL_MAX_LEN); + } + + ReportAppInvokeEvent(&event); +} \ No newline at end of file diff --git a/service/dslm/dslm_hievent.h b/service/dslm/dslm_hievent.h new file mode 100644 index 0000000000000000000000000000000000000000..7d3270514e57cb61c79ab5498c3704aff80adce9 --- /dev/null +++ b/service/dslm/dslm_hievent.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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 DSLM_BIGDATA_EVENT_H +#define DSLM_BIGDATA_EVENT_H + +#include + +#include "dslm_core_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void ReportHiEventInfoSync(const DslmDeviceInfo *info); +void ReportHiEventAppInvoke(const DslmDeviceInfo *info); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_BIGDATA_EVENT_H diff --git a/service/dslm/dslm_inner_process.c b/service/dslm/dslm_inner_process.c new file mode 100644 index 0000000000000000000000000000000000000000..4dbed32e22fea1f224a724700aa1b3ac1bbd253a --- /dev/null +++ b/service/dslm/dslm_inner_process.c @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2021 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 "dslm_inner_process.h" + +#include +#include + +#include "device_security_defines.h" +#include "utils_datetime.h" +#include "utils_log.h" + +#include "dslm_credential.h" +#include "dslm_crypto.h" +#include "dslm_messenger_wrapper.h" +#include "dslm_msg_utils.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NONCE_ALIVE_TIME 60000 + +int32_t CheckAndGenerateChallenge(DslmDeviceInfo *device) +{ + if (device == NULL) { + return ERR_INVALID_PARA; + } + + uint64_t curr = GetMillisecondSinceBoot(); + if ((curr <= device->nonceTimeStamp) || (curr - device->nonceTimeStamp > NONCE_ALIVE_TIME) || device->nonce == 0) { + SECURITY_LOG_INFO("update nonce for device %x", device->machine.machineId); + RandomValue rand = { 0 }; + GenerateRandom(&rand, RAMDOM_MAX_LEN); + device->nonce = *(uint64_t *)&rand.value[0]; + device->nonceTimeStamp = curr; + } + + return SUCCESS; +} + +int32_t SendDeviceInfoRequest(DslmDeviceInfo *device) +{ + if (device == NULL) { + return ERR_INVALID_PARA; + } + + MessageBuff *buff = NULL; + int32_t ret = BuildDeviceSecInfoRequest(device->nonce, &buff); + if (ret != SUCCESS) { + return ERR_INVALID_PARA; + } + device->transNum++; + SendMsgToDevice(device->transNum, &device->identity, buff->buff, buff->length); + + SECURITY_LOG_DEBUG("SendDeviceInfoRequest %s", (char *)buff->buff); + SECURITY_LOG_INFO("SendDeviceInfoRequest challenge is %{public}x***, transNum is %{public}u.", + (uint32_t)device->nonce, (uint32_t)device->transNum); + FreeMessageBuff(buff); + return SUCCESS; +} + +int32_t VerifyDeviceInfoResponse(DslmDeviceInfo *device, const MessageBuff *buff) +{ + if (device == NULL || buff == NULL) { + return ERR_INVALID_PARA; + } + + DslmCredBuff *cred = NULL; + uint64_t nonce = 0; + uint32_t version = 0; + int32_t ret; + + do { + // Parse the msg + ret = ParseDeviceSecInfoResponse(buff, &nonce, &version, &cred); + if (ret != SUCCESS) { + SECURITY_LOG_ERROR("VerifyDeviceInfoResponse error %{public}d.", ret); + break; + } + device->version = version; + if (nonce != device->nonce || nonce == 0) { + ret = ERR_CHALLENGE_ERR; + SECURITY_LOG_ERROR("VerifyDeviceInfoResponse nonce not equal."); + DestroyDslmCred(cred); + break; + } + uint64_t curr = GetMillisecondSinceBoot(); + if ((curr <= device->nonceTimeStamp) || (curr - device->nonceTimeStamp > NONCE_ALIVE_TIME)) { + ret = ERR_CHALLENGE_ERR; + SECURITY_LOG_ERROR("VerifyDeviceInfoResponse nonce expired."); + DestroyDslmCred(cred); + break; + } + // process + ret = DefaultVerifyDslmCred(&device->identity, device->nonce, cred, &device->credInfo); + DestroyDslmCred(cred); + } while (0); + + SECURITY_LOG_INFO("VerifyDeviceInfoResponse challenge is %{public}x***, ret is %{public}d.", (uint32_t)nonce, ret); + return ret; +} + +#ifdef __cplusplus +} +#endif diff --git a/service/dslm/dslm_inner_process.h b/service/dslm/dslm_inner_process.h new file mode 100644 index 0000000000000000000000000000000000000000..9e5533d27c23071977de0f16a7ca500e9ba73a58 --- /dev/null +++ b/service/dslm/dslm_inner_process.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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 DSLM_INNER_PROCESS_H +#define DSLM_INNER_PROCESS_H + +#include +#include + +#include "dslm_core_defines.h" +#include "dslm_msg_serialize.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t CheckAndGenerateChallenge(DslmDeviceInfo *device); + +int32_t SendDeviceInfoRequest(DslmDeviceInfo *device); + +int32_t VerifyDeviceInfoResponse(DslmDeviceInfo *device, const MessageBuff *buff); +#ifdef __cplusplus +} +#endif + +#endif // DSLM_INNER_PROCESS_H diff --git a/service/dslm/dslm_msg_utils.c b/service/dslm/dslm_msg_utils.c new file mode 100644 index 0000000000000000000000000000000000000000..9051299543faee380eee35e480146fb83301d0b9 --- /dev/null +++ b/service/dslm/dslm_msg_utils.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2021 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 "dslm_msg_utils.h" + +#include +#include + +#include "utils_base64.h" +#include "utils_hexstring.h" +#include "utils_json.h" +#include "utils_log.h" +#include "utils_mem.h" + +#include "device_security_defines.h" +#include "dslm_core_defines.h" +#include "dslm_credential.h" + +#define CHALLENGE_STRING_LENGTH 32 + +static uint8_t *GenerateSecInfoResponseJson(uint64_t challenge, const DslmCredBuff *cred) +{ + uint8_t *credBase64Str = NULL; + uint8_t *out = NULL; + + JsonHandle head = CreateJson(NULL); + if (head == NULL) { + return NULL; + } + + JsonHandle body = CreateJson(NULL); + if (body == NULL) { + DestroyJson(head); + return NULL; + } + + AddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_RESPONSE); + AddFieldJsonToJson(head, FIELD_PAYLOAD, body); + + AddFieldIntToJson(body, FIELD_VERSION, GetCurrentVersion()); + AddFieldIntToJson(body, FIELD_CRED_TYPE, cred->type); + + char challengeStr[CHALLENGE_STRING_LENGTH] = {0}; + char *nonce = &challengeStr[0]; + ByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH); + challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0; + AddFieldStringToJson(body, FIELD_CHALLENGE, nonce); + + credBase64Str = Base64EncodeApp(cred->credVal, cred->credLen); + // it is ok when credBase64Str is NULL + AddFieldStringToJson(body, FIELD_CRED_INFO, (char *)credBase64Str); + out = (uint8_t *)ConvertJsonToString(head); + + if (head != NULL) { + DestroyJson(head); + body = NULL; // no need to free body + } + + if (body != NULL) { + DestroyJson(body); + } + if (credBase64Str != NULL) { + FREE(credBase64Str); + } + return out; +} + +static uint8_t *GenerateSecInfoRequestJson(uint64_t challenge) +{ + JsonHandle head = CreateJson(NULL); + if (head == NULL) { + return NULL; + } + JsonHandle body = CreateJson(NULL); + if (body == NULL) { + DestroyJson(head); + return NULL; + } + + char challengeStr[CHALLENGE_STRING_LENGTH] = {0}; + char *nonce = &challengeStr[0]; + ByteToHexString((uint8_t *)&challenge, sizeof(challenge), (uint8_t *)nonce, CHALLENGE_STRING_LENGTH); + challengeStr[CHALLENGE_STRING_LENGTH - 1] = 0; + + AddFieldIntToJson(head, FIELD_MESSAGE, MSG_TYPE_DSLM_CRED_REQUEST); + AddFieldJsonToJson(head, FIELD_PAYLOAD, body); + AddFieldIntToJson(body, FIELD_VERSION, GetCurrentVersion()); + + AddFieldStringToJson(body, FIELD_CHALLENGE, nonce); + + CredType credTypeArray[MAX_CRED_ARRAY_SIZE] = {0}; + int32_t arraySize = GetSupportedCredTypes(credTypeArray, MAX_CRED_ARRAY_SIZE); + AddFieldIntArrayToJson(body, FIELD_SUPPORT, (const int32_t *)credTypeArray, arraySize); + + uint8_t *out = (uint8_t *)ConvertJsonToString(head); + + if (head != NULL) { + DestroyJson(head); + body = NULL; // no need to free body + } + + if (body != NULL) { + DestroyJson(body); + } + return out; +} + +int32_t BuildDeviceSecInfoRequest(uint64_t challenge, MessageBuff **msg) +{ + if ((msg == NULL) || (*msg != NULL)) { + return ERR_INVALID_PARA; + } + + MessageBuff *out = MALLOC(sizeof(MessageBuff)); + if (out == NULL) { + return ERR_NO_MEMORY; + } + memset_s(out, sizeof(MessageBuff), 0, sizeof(MessageBuff)); + + out->buff = GenerateSecInfoRequestJson(challenge); + if (out->buff == NULL) { + FREE(out); + return ERR_JSON_ERR; + } + out->length = strlen((char *)out->buff) + 1; + *msg = out; + return SUCCESS; +} + +int32_t ParseDeviceSecInfoRequest(const MessageBuff *buff, RequestObject *obj) +{ + if (buff == NULL || obj == NULL || buff->buff == NULL) { + return ERR_INVALID_PARA; + } + SECURITY_LOG_DEBUG("ParseDeviceSecInfoRequest msg is %s", (char *)buff->buff); + + JsonHandle handle = CreateJson((const char *)buff->buff); + if (handle == NULL) { + return ERR_INVALID_PARA; + } + + const char *nonceStr = GetJsonFieldString(handle, FIELD_CHALLENGE); + if (nonceStr == NULL) { + DestroyJson(handle); + return ERR_NO_CHALLENGE; + } + + int32_t ret = HexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&obj->challenge, sizeof(obj->challenge)); + if (ret != 0) { + DestroyJson(handle); + return ERR_NO_CHALLENGE; + } + + uint32_t verNum = (uint32_t)GetJsonFieldInt(handle, FIELD_VERSION); + + int32_t arraySize = GetJsonFieldIntArray(handle, FIELD_SUPPORT, (int32_t *)obj->credArray, MAX_CRED_ARRAY_SIZE); + + obj->version = verNum; + obj->arraySize = arraySize; + + DestroyJson(handle); + + return SUCCESS; +} + +int32_t BuildDeviceSecInfoResponse(uint64_t challenge, const DslmCredBuff *cred, MessageBuff **msg) +{ + if ((cred == NULL) || (msg == NULL) || (*msg != NULL)) { + return ERR_INVALID_PARA; + } + MessageBuff *out = MALLOC(sizeof(MessageBuff)); + if (out == NULL) { + return ERR_NO_MEMORY; + } + + out->buff = (uint8_t *)GenerateSecInfoResponseJson(challenge, cred); + if (out->buff == NULL) { + FREE(out); + return ERR_JSON_ERR; + } + out->length = strlen((char *)out->buff) + 1; + + *msg = out; + return SUCCESS; +} + +int32_t ParseDeviceSecInfoResponse(const MessageBuff *msg, uint64_t *challenge, uint32_t *version, DslmCredBuff **cred) +{ + if (msg == NULL || challenge == NULL || version == NULL || cred == NULL) { + return ERR_INVALID_PARA; + } + + if (msg->buff == NULL || *cred != NULL) { + return ERR_INVALID_PARA; + } + + JsonHandle handle = CreateJson((const char *)msg->buff); + if (handle == NULL) { + return ERR_INVALID_PARA; + } + + const char *nonceStr = GetJsonFieldString(handle, FIELD_CHALLENGE); + if (nonceStr == NULL) { + DestroyJson(handle); + return ERR_NO_CHALLENGE; + } + uint64_t nonceNum = 0; + int32_t ret = HexStringToByte(nonceStr, strlen(nonceStr), (uint8_t *)&nonceNum, sizeof(uint64_t)); + if (ret != 0) { + DestroyJson(handle); + return ERR_NO_CHALLENGE; + } + + uint32_t type = (uint32_t)GetJsonFieldInt(handle, FIELD_CRED_TYPE); + uint32_t verNum = GetJsonFieldInt(handle, FIELD_VERSION); + + const char *credStr = GetJsonFieldString(handle, FIELD_CRED_INFO); + if (credStr == NULL) { + DestroyJson(handle); + return ERR_NO_CRED; + } + + uint8_t *credBuf = NULL; + uint32_t credLen = Base64DecodeApp((uint8_t *)credStr, &credBuf); + if (credBuf == NULL) { + DestroyJson(handle); + return ERR_NO_CRED; + } + + DslmCredBuff *out = CreateDslmCred((CredType)type, credLen, credBuf); + if (out == NULL) { + DestroyJson(handle); + FREE(credBuf); + return ERR_NO_MEMORY; + } + + DestroyJson(handle); + FREE(credBuf); + *version = verNum; + *challenge = nonceNum; + *cred = out; + return SUCCESS; +} diff --git a/service/dslm/dslm_msg_utils.h b/service/dslm/dslm_msg_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..1e0d120eee9f3a48e2fa7a4d192abb2cb504938c --- /dev/null +++ b/service/dslm/dslm_msg_utils.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 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 DSLM_MSG_UTILS_H +#define DSLM_MSG_UTILS_H + +#include + +#include "dslm_cred.h" +#include "dslm_msg_serialize.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define FIELD_VERSION "version" +#define FIELD_CHALLENGE "challenge" +#define FIELD_SUPPORT "support" +#define FIELD_CRED_TYPE "type" +#define FIELD_CRED_INFO "info" + +int32_t BuildDeviceSecInfoRequest(uint64_t challenge, MessageBuff **msg); + +int32_t BuildDeviceSecInfoResponse(uint64_t challenge, const DslmCredBuff *cred, MessageBuff **msg); + +int32_t ParseDeviceSecInfoRequest(const MessageBuff *msg, RequestObject *obj); + +int32_t ParseDeviceSecInfoResponse(const MessageBuff *msg, uint64_t *challenge, uint32_t *version, DslmCredBuff **cred); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_MSG_UTILS_H diff --git a/service/include/dslm_bigdata.h b/service/include/dslm_bigdata.h new file mode 100644 index 0000000000000000000000000000000000000000..4e1c4c63295a900c1bee54a988957230b7736a90 --- /dev/null +++ b/service/include/dslm_bigdata.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 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 SERVICE_DSLM_BIGDATA_H +#define SERVICE_DSLM_BIGDATA_H + +#ifdef __cplusplus +#include +constexpr int MODEL_MAX_LEN = 128; +constexpr int PKG_NAME_MAX_LEN = 256; +#else +#include +#define MODEL_MAX_LEN 128 +#define PKG_NAME_MAX_LEN 256 +#endif + +typedef struct AppInvokeEvent { + int32_t uid; + int32_t costTime; + int32_t retCode; + int32_t secLevel; + int32_t retMode; + char localModel[MODEL_MAX_LEN]; + char targetModel[MODEL_MAX_LEN]; + char pkgName[PKG_NAME_MAX_LEN]; +} AppInvokeEvent; + +typedef struct SecurityInfoSyncEvent { + char localModel[MODEL_MAX_LEN]; + char targetModel[MODEL_MAX_LEN]; + uint64_t localVersion; + uint64_t targetVersion; + int32_t credType; + int32_t retCode; + int32_t costTime; + int32_t secLevel; +} SecurityInfoSyncEvent; + +#ifdef __cplusplus +extern "C" { +#endif + +void ReportAppInvokeEvent(const AppInvokeEvent *event) __attribute__((weak)); + +void ReportSecurityInfoSyncEvent(const SecurityInfoSyncEvent *event) __attribute__((weak)); + +#ifdef __cplusplus +} +#endif + +#endif // SERVICE_DSLM_BIGDATA_H diff --git a/service/include/dslm_callback_info.h b/service/include/dslm_callback_info.h new file mode 100644 index 0000000000000000000000000000000000000000..8e632edda0be252cc2d91f5fd315e8cff43aa18a --- /dev/null +++ b/service/include/dslm_callback_info.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 DSLM_CALLBACK_INFO_H +#define DSLM_CALLBACK_INFO_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DslmCallbackInfo { + uint32_t level; + const uint8_t *extraBuff; + uint32_t extraLen; +} DslmCallbackInfo; + +typedef void RequestCallback(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_CALLBACK_INFO_H diff --git a/service/include/dslm_core_process.h b/service/include/dslm_core_process.h new file mode 100644 index 0000000000000000000000000000000000000000..26942ebf7e1cd075ecb8f52f9c102973ea268c1f --- /dev/null +++ b/service/include/dslm_core_process.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 DSLM_CORE_PROCESS_H +#define DSLM_CORE_PROCESS_H + +#include +#include + +#include "device_security_defines.h" + +#include "dslm_callback_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int32_t OnPeerMsgRequestInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len); + +int32_t OnPeerMsgResponseInfoReceived(const DeviceIdentify *deviceId, const uint8_t *msg, uint32_t len); + +int32_t OnRequestDeviceSecLevelInfo(const DeviceIdentify *deviceId, const RequestOption *option, uint32_t cookie, + RequestCallback callback); + +int32_t OnMsgSendResultNotifier(const DeviceIdentify *deviceId, uint64_t transNo, uint32_t result); + +int32_t OnPeerStatusReceiver(const DeviceIdentify *deviceId, uint32_t status, uint32_t devType); + +bool InitDslmProcess(); + +bool DeinitDslmProcess(); + +bool InitSelfDeviceSecureLevel(); + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_CORE_PROCESS_H diff --git a/service/include/dslm_crypto.h b/service/include/dslm_crypto.h new file mode 100644 index 0000000000000000000000000000000000000000..c4b75155dfb15428de6a04e3195d1a0d48c69d17 --- /dev/null +++ b/service/include/dslm_crypto.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 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 DSLM_CRYPTO_H +#define DSLM_CRYPTO_H + +#include +#include + +#define RAMDOM_MAX_LEN 32 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct RandomValue { + uint32_t length; + uint8_t value[RAMDOM_MAX_LEN]; +} RandomValue; + +void GenerateRandom(RandomValue *rand, uint32_t length); + +#ifdef __cplusplus +} +#endif + +#endif /* DSLM_CRYPTO_H */ \ No newline at end of file diff --git a/service/include/dslm_hidumper.h b/service/include/dslm_hidumper.h new file mode 100644 index 0000000000000000000000000000000000000000..c463bd07e75c15b3adab85d511add8b95bb315e3 --- /dev/null +++ b/service/include/dslm_hidumper.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 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 FULL_DSLM_HIDUMPER_H +#define FULL_DSLM_HIDUMPER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void DslmDumper(int fd); + +#ifdef __cplusplus +} +#endif // FULL_DSLM_HIDUMPER_H + +#endif diff --git a/service/include/dslm_messenger_wrapper.h b/service/include/dslm_messenger_wrapper.h new file mode 100644 index 0000000000000000000000000000000000000000..73b092838427c9782f4b4262ec534bcf1fda58a8 --- /dev/null +++ b/service/include/dslm_messenger_wrapper.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 SERVICE_MSG_MESSENGER_WRAPPER_H +#define SERVICE_MSG_MESSENGER_WRAPPER_H + +#include +#include + +#include "device_security_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ONLINE 1 +#define OFFLINE 0 + +typedef int32_t (*MessageReceiver)(const DeviceIdentify *devId, const uint8_t *msg, uint32_t len); + +typedef int32_t (*StatusReceiver)(const DeviceIdentify *devId, uint32_t status, uint32_t devType); + +typedef int32_t (*SendResultNotifier)(const DeviceIdentify *devId, uint64_t transNo, uint32_t result); + +typedef int32_t (*DeviceProcessor)(const DeviceIdentify *devId, uint32_t devType, void *para); + +void SendMsgToDevice(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen); + +uint32_t InitMessenger(const MessageReceiver messageReceiver, const StatusReceiver statusReceiver, + const SendResultNotifier notifier); + +uint32_t DeinitMessenger(); + +bool GetMessengerStatus(); + +bool GetPeerDeviceOnlineStatus(const DeviceIdentify *devId, uint32_t *devType); + +const DeviceIdentify *GetSelfDevice(uint32_t *devType); + +#ifdef __cplusplus +} +#endif + +#endif // SERVICE_MSG_MESSENGER_WRAPPER_H diff --git a/service/include/dslm_msg_serialize.h b/service/include/dslm_msg_serialize.h new file mode 100644 index 0000000000000000000000000000000000000000..dd22904ecf9e9c094271e6fe87c80e9fbbdef4c6 --- /dev/null +++ b/service/include/dslm_msg_serialize.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 DSLM_MSG_SERIALIZE_H +#define DSLM_MSG_SERIALIZE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MSG_TYPE_DSLM_CRED_REQUEST 0x1 +#define MSG_TYPE_DSLM_CRED_RESPONSE 0x2 + +#define FIELD_MESSAGE "message" +#define FIELD_PAYLOAD "payload" + +/* raw msg from soft bus */ +typedef struct MessageBuff { + uint32_t length; + uint8_t *buff; +} MessageBuff; + +/* parsed fist level msg */ +typedef struct MessagePacket { + uint32_t type; + uint32_t length; + uint8_t *payload; +} MessagePacket; + +MessagePacket *ParseMessage(const MessageBuff *buff); + +MessageBuff *SerializeMessage(const MessagePacket *packet); + +void FreeMessagePacket(MessagePacket *packet); + +void FreeMessageBuff(MessageBuff *buff); + +#ifdef __cplusplus +} +#endif + +#endif /* DSLM_MSG_SERIALIZE_H */ \ No newline at end of file diff --git a/service/include/dslm_notify_node.h b/service/include/dslm_notify_node.h new file mode 100644 index 0000000000000000000000000000000000000000..45ab0d254eeaf849e7a1ce75b393f794b7830f71 --- /dev/null +++ b/service/include/dslm_notify_node.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021 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 DSLM_NOTIFY_NODE_H +#define DSLM_NOTIFY_NODE_H + +#include + +#include "utils_list.h" + +#include "dslm_callback_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DslmNotifyListNode { + ListNode linkNode; + uint64_t start; + uint32_t keep; + uint32_t cookie; + uint32_t extra; + RequestCallback *requestCallback; +} DslmNotifyListNode; + +#ifdef __cplusplus +} +#endif + +#endif // DSLM_NOTIFY_NODE_H diff --git a/service/msg/BUILD.gn b/service/msg/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..855985a91551fd10bd709085de95a5b66aad750d --- /dev/null +++ b/service/msg/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# service_msg object +ohos_source_set("service_msg_obj") { + sources = [ "dslm_messenger_wrapper.c" ] + + include_dirs = [ + "//base/security/devicesecuritylevel/interfaces/include", + "//base/security/devicesecuritylevel/service/include", + ] + + deps = [ + "//base/security/devicesecuritylevel/baselib/msglib:messenger_static", + "//base/security/devicesecuritylevel/baselib/utils:utils_static", + ] + + external_deps = [ + "hilog_native:libhilog", + "utils_base:utils", + ] + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/service/msg/dslm_messenger_wrapper.c b/service/msg/dslm_messenger_wrapper.c new file mode 100644 index 0000000000000000000000000000000000000000..555b25523a845b496616fe245d04d39252b8187a --- /dev/null +++ b/service/msg/dslm_messenger_wrapper.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021 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 "dslm_messenger_wrapper.h" + +#include "messenger.h" + +#include "utils_mutex.h" + +#define PKG_NAME "ohos.dslm" +#define SESSION_NAME "device.security.level" + +Messenger *g_messenger = NULL; +static Mutex g_mutex = INITED_MUTEX; + +uint32_t InitMessenger(const MessageReceiver messageReceiver, const StatusReceiver statusReceiver, + const SendResultNotifier notifier) +{ + MessengerConfig config = { + .pkgName = PKG_NAME, + .sessName = SESSION_NAME, + .messageReceiver = messageReceiver, + .statusReceiver = statusReceiver, + .sendResultNotifier = notifier, + }; + InitMutex(&g_mutex); + LockMutex(&g_mutex); + g_messenger = CreateMessenger(&config); + UnlockMutex(&g_mutex); + if (g_messenger == NULL) { + return ERR_MSG_NOT_INIT; + } + + return SUCCESS; +} + +uint32_t DeinitMessenger() +{ + LockMutex(&g_mutex); + if (g_messenger == NULL) { + UnlockMutex(&g_mutex); + return SUCCESS; + } + DestroyMessenger(g_messenger); + UnlockMutex(&g_mutex); + return SUCCESS; +} + +bool GetMessengerStatus() +{ + LockMutex(&g_mutex); + if (g_messenger == NULL) { + UnlockMutex(&g_mutex); + return false; + } + bool ret = IsMessengerReady(g_messenger); + UnlockMutex(&g_mutex); + return ret; +} + +void SendMsgToDevice(uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) +{ + LockMutex(&g_mutex); + if (g_messenger == NULL) { + UnlockMutex(&g_mutex); + return; + } + SendMsgTo(g_messenger, transNo, devId, msg, msgLen); + UnlockMutex(&g_mutex); + return; +} + +bool GetPeerDeviceOnlineStatus(const DeviceIdentify *devId, uint32_t *devType) +{ + LockMutex(&g_mutex); + if (g_messenger == NULL) { + UnlockMutex(&g_mutex); + return false; + } + if (devId == NULL || devType == NULL) { + UnlockMutex(&g_mutex); + return false; + } + bool ret = GetDeviceOnlineStatus(g_messenger, devId, devType); + UnlockMutex(&g_mutex); + return ret; +} + +const DeviceIdentify *GetSelfDevice(uint32_t *devType) +{ + LockMutex(&g_mutex); + static uint32_t type = 0; + static DeviceIdentify deviceId = { 0, { 0 } }; + if (deviceId.length == 0 || deviceId.identity[0] == 0) { + if (g_messenger != NULL) { + GetSelfDeviceIdentify(g_messenger, &deviceId, &type); + } + } + if (devType != NULL) { + *devType = type; + } + UnlockMutex(&g_mutex); + return &deviceId; +} diff --git a/service/sa/BUILD.gn b/service/sa/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..1efe7918634d17ba5c6a34f4ec41572d5ed11cf3 --- /dev/null +++ b/service/sa/BUILD.gn @@ -0,0 +1,62 @@ +# Copyright (C) 2021 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("//build/ohos.gni") + +# sa lib +ohos_static_library("service_sa_static") { + sources = [ + "common/dslm_rpc_process.c", + "full/dslm_callback_proxy.cpp", + "full/dslm_ipc_process.cpp", + "full/dslm_service.cpp", + ] + + include_dirs = [ + "//base/security/devicesecuritylevel/common/include", + "//base/security/devicesecuritylevel/interfaces/include", + "//base/security/devicesecuritylevel/service/include", + "//base/security/devicesecuritylevel/service/sa/common", + ] + + deps = [ + "//base/security/devicesecuritylevel/baselib/utils:utils_static", + "//base/security/devicesecuritylevel/service/bigdata:service_bigdata_obj", + "//base/security/devicesecuritylevel/service/common:service_common_obj", + "//base/security/devicesecuritylevel/service/dslm:service_dslm_obj", + "//base/security/devicesecuritylevel/service/msg:service_msg_obj", + ] + + external_deps = [ + "ipc:ipc_core", + "safwk:system_ability_fwk", + "utils_base:utils", + ] + + if (is_large_system) { + external_deps += [ + "hilog:libhilog", + "samgr:samgr_proxy", + ] + } + + if (is_standard_system) { + external_deps += [ + "hilog_native:libhilog", + "samgr_standard:samgr_proxy", + ] + } + + part_name = "devicesecuritylevel" + subsystem_name = "security" +} diff --git a/service/sa/common/dslm_rpc_process.c b/service/sa/common/dslm_rpc_process.c new file mode 100644 index 0000000000000000000000000000000000000000..f9b383d7e30125525169782d7e0d981cd0a8a1ec --- /dev/null +++ b/service/sa/common/dslm_rpc_process.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2021 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 "dslm_rpc_process.h" + +#include + +#include "utils_log.h" + +#include "dslm_core_process.h" +#include "dslm_messenger_wrapper.h" +#include "dslm_msg_serialize.h" + +#define SLEEP_TIME (1000 * 500) +#define TRY_TIMES 20 + +int32_t OnPeerMsgReceived(const DeviceIdentify *devId, const uint8_t *msg, uint32_t len) +{ + if (devId == NULL || msg == NULL || len == 0) { + SECURITY_LOG_ERROR("OnPeerMsgReceived params is NULL, len = %{public}u", len); + return ERR_INVALID_PARA; + } + + const MessageBuff buff = { + .buff = (uint8_t *)msg, + .length = len + }; + int32_t ret = SUCCESS; + MessagePacket *packet = ParseMessage(&buff); + if (packet == NULL) { + SECURITY_LOG_ERROR("OnPeerMsgReceived packet is NULL"); + return ERR_INVALID_PARA; + } + if (packet->payload == NULL) { + FreeMessagePacket(packet); + SECURITY_LOG_ERROR("OnPeerMsgReceived packet->payload is NULL"); + return ERR_INVALID_PARA; + } + + switch (packet->type) { + case MSG_TYPE_DSLM_CRED_REQUEST: + ret = OnPeerMsgRequestInfoReceived(devId, packet->payload, packet->length); + break; + case MSG_TYPE_DSLM_CRED_RESPONSE: + ret = OnPeerMsgResponseInfoReceived(devId, packet->payload, packet->length); + break; + default: + break; + } + if (ret != SUCCESS) { + SECURITY_LOG_ERROR("OnPeerMsgReceived ret = %{public}d, packet->type = %{public}u", ret, packet->type); + } + FreeMessagePacket(packet); + return ret; +} + +int32_t OnSendResultNotifier(const DeviceIdentify *devId, uint64_t transNo, uint32_t result) +{ + return OnMsgSendResultNotifier(devId, transNo, result); +} + +uint32_t InitService() +{ + uint32_t times = 0; + uint32_t ret = InitMessenger(OnPeerMsgReceived, OnPeerStatusReceiver, OnSendResultNotifier); + if (ret != SUCCESS) { + SECURITY_LOG_ERROR("InitService InitMessenger ret = %{public}u", ret); + return ret; + } + + SECURITY_LOG_INFO("InitService InitMessenger success"); + + while (true) { + if (InitDslmProcess()) { + break; + } + usleep(SLEEP_TIME); + if (times > TRY_TIMES) { + SECURITY_LOG_ERROR("wait SoftBus timeout"); + break; + } + times++; + } + return SUCCESS; +} + +void UnInitService() +{ + DeinitDslmProcess(); + DeinitMessenger(); + return; +} diff --git a/service/sa/common/dslm_rpc_process.h b/service/sa/common/dslm_rpc_process.h new file mode 100644 index 0000000000000000000000000000000000000000..44cc4fb3b7e9666118b87644c1c038f098f21db4 --- /dev/null +++ b/service/sa/common/dslm_rpc_process.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 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 COMMON_DSLM_RPC_PROCESS_H +#define COMMON_DSLM_RPC_PROCESS_H + +#include "stdint.h" +#include "stdlib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +uint32_t InitService(); + +void UnInitService(); + +#ifdef __cplusplus +} +#endif + +#endif // COMMON_DSLM_RPC_PROCESS_H diff --git a/service/sa/full/dslm_callback_proxy.cpp b/service/sa/full/dslm_callback_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9bc143beac566aedf18286b33af211d2b9bddd51 --- /dev/null +++ b/service/sa/full/dslm_callback_proxy.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 "dslm_callback_proxy.h" + +#include + +#include "utils_log.h" + +#include "device_security_defines.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS::HiviewDFX; +DslmCallbackProxy::DslmCallbackProxy(const sptr &impl) : IRemoteProxy(impl) +{ +} + +int32_t DslmCallbackProxy::ResponseDeviceSecurityLevel(uint32_t cookie, const ResponseInfo &response) +{ + MessageParcel data; + MessageParcel reply; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + return ERR_INVALID_PARA; + } + + data.WriteUint32(cookie); + data.WriteUint32(response.result); + data.WriteUint32(response.level); + + if (response.extraBuff != nullptr && response.extraLen != 0) { + data.WriteUint32(response.extraLen); + data.WriteBuffer(response.extraBuff, response.extraLen); + } + + MessageOption ipcOption = {MessageOption::TF_ASYNC}; + return Remote()->SendRequest(CMD_SET_DEVICE_SECURITY_LEVEL, data, reply, ipcOption); +} + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS diff --git a/service/sa/full/dslm_callback_proxy.h b/service/sa/full/dslm_callback_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..402d94a27f09f7ecb23b584aa4953f1e3ef2468e --- /dev/null +++ b/service/sa/full/dslm_callback_proxy.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021 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 DSLM_CALLBACK_PROXY +#define DSLM_CALLBACK_PROXY + +#include "iremote_proxy.h" +#include "nocopyable.h" + +#include "idevice_security_level.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +using namespace OHOS; +class DslmCallbackProxy : public IRemoteProxy { +public: + DISALLOW_COPY_AND_MOVE(DslmCallbackProxy); + explicit DslmCallbackProxy(const sptr &impl); + virtual ~DslmCallbackProxy() = default; + + struct ResponseInfo { + uint32_t result; + uint32_t level; + const uint8_t *extraBuff; + uint32_t extraLen; + }; + + int32_t ResponseDeviceSecurityLevel(uint32_t cookie, const ResponseInfo &response); + +private: + static inline BrokerDelegator delegator_; +}; + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS + +#endif // DSLM_CALLBACK_PROXY \ No newline at end of file diff --git a/service/sa/full/dslm_ipc_process.cpp b/service/sa/full/dslm_ipc_process.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d553b0e956ef15386b6537a06678b7c9aed7f831 --- /dev/null +++ b/service/sa/full/dslm_ipc_process.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2021 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 "dslm_ipc_process.h" + +#include +#include + +#include "utils_log.h" + +#include "dslm_callback_proxy.h" +#include "dslm_core_process.h" + +namespace { +constexpr uint32_t DFT_TIMEOUT = 45; +constexpr uint32_t MAX_TIMEOUT = 60; +constexpr uint32_t MIN_TIMEOUT = 1; +constexpr uint32_t WARAING_GATE = 64; +} + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { + +static void ProcessCallback(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info) +{ + if ((cookie == 0) || (info == nullptr)) { + return; + } + auto object = Singleton::GetInstance().Pop(cookie); + + auto proxy = iface_cast(object); + if (object == nullptr) { + SECURITY_LOG_ERROR("ProcessCallback iface_cast error."); + return; + } + DslmCallbackProxy::ResponseInfo resInfo = {result, info->level, info->extraBuff, info->extraLen}; + proxy->ResponseDeviceSecurityLevel(cookie, resInfo); +} + +DslmIpcProcess::DslmIpcProcess() +{ +} + +DslmIpcProcess::~DslmIpcProcess() +{ +} + +int32_t DslmIpcProcess::DslmGetRequestFromParcel(MessageParcel &data, DeviceIdentify &identify, RequestOption &option, + sptr &object, uint32_t &cookie) +{ + uint32_t expected = sizeof(DeviceIdentify) + sizeof(RequestOption) + sizeof(uint32_t); + uint32_t actual = data.GetReadableBytes(); + if (expected >= actual) { + SECURITY_LOG_ERROR("DslmGetRequestFromParcel unexpected input, length error"); + return ERR_INVALID_PARA; + } + + identify.length = data.ReadUint32(); + + const uint8_t *dataRead = data.ReadBuffer(DEVICE_ID_MAX_LEN); + if (dataRead == nullptr) { + SECURITY_LOG_ERROR("DslmGetRequestFromParcel unexpected input, buffer error"); + return ERR_INVALID_PARA; + } + if (memcpy_s(identify.identity, DEVICE_ID_MAX_LEN, dataRead, DEVICE_ID_MAX_LEN) != EOK) { + SECURITY_LOG_ERROR("DslmGetRequestFromParcel unexpected input, buffer copy error"); + return ERR_INVALID_PARA; + } + + option.challenge = data.ReadUint64(); + option.timeout = data.ReadUint32(); + if (option.timeout < MIN_TIMEOUT || option.timeout > MAX_TIMEOUT) { + option.timeout = DFT_TIMEOUT; + } + + option.extra = data.ReadUint32(); + + object = data.ReadRemoteObject(); + if (object == nullptr) { + SECURITY_LOG_ERROR("DslmGetRequestFromParcel unexpected input, callback ipc error"); + return ERR_INVALID_PARA; + } + cookie = data.ReadUint32(); + if (cookie == 0) { + SECURITY_LOG_ERROR("DslmGetRequestFromParcel unexpected input, cookie error"); + return ERR_INVALID_PARA; + } + + return SUCCESS; +} + +int32_t DslmIpcProcess::DslmSetResponseToParcel(MessageParcel &reply, int32_t status) +{ + auto success = reply.WriteUint32(status); + if (success == false) { + return ERR_IPC_RET_PARCEL_ERR; + } + return SUCCESS; +} + +int32_t DslmIpcProcess::DslmProcessGetDeviceSecurityLevel(MessageParcel &data, MessageParcel &reply) +{ + DeviceIdentify identity; + RequestOption option; + sptr callback; + uint32_t cookie; + + int32_t ret = DslmGetRequestFromParcel(data, identity, option, callback, cookie); + if (ret != SUCCESS) { + SECURITY_LOG_ERROR("ProcessGetDeviceSecurityLevel DslmGetRequestFromParcel failed, ret = %{public}d", ret); + return ret; + } + + Singleton::GetInstance().Push(cookie, callback); + + ret = OnRequestDeviceSecLevelInfo(&identity, &option, cookie, ProcessCallback); + if (ret != SUCCESS) { + Singleton::GetInstance().Pop(cookie); + SECURITY_LOG_ERROR("ProcessGetDeviceSecurityLevel OnRequestDeviceSecLevelInfo failed, ret = %{public}d", ret); + return ret; + } + + ret = DslmSetResponseToParcel(reply, cookie); + if (ret != SUCCESS) { + Singleton::GetInstance().Pop(cookie); + SECURITY_LOG_ERROR("ProcessGetDeviceSecurityLevel DslmSetResponseToParcel failed, ret = %{public}d", ret); + return ret; + } + return SUCCESS; +} + +DslmIpcProcess::RemoteHolder::RemoteHolder() +{ +} + +DslmIpcProcess::RemoteHolder::~RemoteHolder() +{ +} + +bool DslmIpcProcess::RemoteHolder::Push(uint32_t cookie, const sptr object) +{ + std::lock_guard lock(mutex_); + map_[cookie] = object; + if (map_.size() > WARAING_GATE) { + SECURITY_LOG_WARN("DslmIpcProcess remote objects max warning"); + } + return true; +} + +const sptr DslmIpcProcess::RemoteHolder::Pop(uint32_t cookie) +{ + std::lock_guard lock(mutex_); + auto iter = map_.find(cookie); + if (iter == map_.end()) { + return nullptr; + } + auto obj = iter->second; + map_.erase(iter); + return obj; +} + +} // DeviceSecurityLevel +} // Security +} // OHOS diff --git a/service/sa/full/dslm_ipc_process.h b/service/sa/full/dslm_ipc_process.h new file mode 100644 index 0000000000000000000000000000000000000000..c090d944aca6dfeea812e9983f6af1e093e156c7 --- /dev/null +++ b/service/sa/full/dslm_ipc_process.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2021 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 DSLM_IPC_PROCESS_H +#define DSLM_IPC_PROCESS_H + +#include + +#include "iremote_object.h" +#include "message_parcel.h" +#include "singleton.h" + +#include "device_security_defines.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +class DslmIpcProcess { + DECLARE_SINGLETON(DslmIpcProcess); + +public: + int32_t DslmProcessGetDeviceSecurityLevel(MessageParcel &data, MessageParcel &reply); + + class RemoteHolder { + DECLARE_SINGLETON(RemoteHolder); + + public: + bool Push(uint32_t cookie, const sptr object); + const sptr Pop(uint32_t cookie); + + private: + std::map> map_; + std::mutex mutex_; + }; + +private: + int32_t DslmGetRequestFromParcel(MessageParcel &data, DeviceIdentify &identify, RequestOption &option, + sptr &object, uint32_t &cookie); + + int32_t DslmSetResponseToParcel(MessageParcel &reply, int32_t status); +}; + +} // DeviceSecurityLevel +} // Security +} // OHOS + +#endif // DSLM_IPC_PROCESS_H \ No newline at end of file diff --git a/service/sa/full/dslm_service.cpp b/service/sa/full/dslm_service.cpp new file mode 100644 index 0000000000000000000000000000000000000000..271434313fedb14790aca029e10ef6860feba91b --- /dev/null +++ b/service/sa/full/dslm_service.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2021 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 "dslm_service.h" + +#include + +#include "utils_log.h" + +#include "dslm_hidumper.h" +#include "dslm_ipc_process.h" +#include "dslm_rpc_process.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +REGISTER_SYSTEM_ABILITY_BY_ID(DslmService, SA_ID_DEVICE_SECURITY_MANAGER_SERVICE, true); + +DslmService::DslmService(int32_t saId, bool runOnCreate) : SystemAbility(saId, runOnCreate) +{ + SECURITY_LOG_INFO("DslmService::DslmService"); +} + +void DslmService::OnStart() +{ + SECURITY_LOG_INFO("DslmService::OnStart service"); + if (!Publish(this)) { + SECURITY_LOG_ERROR("DslmService::OnStart Publish service failed."); + } + + std::thread t([this]() { + if (InitService() == SUCCESS) { + SECURITY_LOG_INFO("DslmService::OnStart InitService success."); + return; + } + }); + t.detach(); +} + +void DslmService::OnStop() +{ + UnInitService(); + SECURITY_LOG_INFO("DslmService::OnStop service stop."); +} + +int32_t DslmService::Dump(int fd, const std::vector &args) +{ + DslmDumper(fd); + return 0; +} + +int32_t DslmService::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) +{ + do { + if (IDeviceSecurityLevel::GetDescriptor() != data.ReadInterfaceToken()) { + SECURITY_LOG_ERROR("local descriptor is not equal remote"); + break; + } + switch (code) { + case CMD_GET_DEVICE_SECURITY_LEVEL: + return ProcessGetDeviceSecurityLevel(data, reply); + default: + break; + } + } while (0); + + return ERR_REQUEST_CODE_ERR; +} + +int32_t DslmService::ProcessGetDeviceSecurityLevel(MessageParcel &data, MessageParcel &reply) +{ + return Singleton::GetInstance().DslmProcessGetDeviceSecurityLevel(data, reply); +} + +} // namespace DeviceSecurityLevel +} // namespace Security +} // namespace OHOS diff --git a/service/sa/full/dslm_service.h b/service/sa/full/dslm_service.h new file mode 100644 index 0000000000000000000000000000000000000000..86018654f2ce86fe695e884440623754a7e2a51f --- /dev/null +++ b/service/sa/full/dslm_service.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021 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 DSLM_SERVICE_H +#define DSLM_SERVICE_H + +#include "iremote_stub.h" +#include "nocopyable.h" +#include "system_ability.h" + +#include "idevice_security_level.h" + +namespace OHOS { +namespace Security { +namespace DeviceSecurityLevel { +class DslmService : public SystemAbility, public IRemoteStub { + DECLARE_SYSTEM_ABILITY(DslmService); + +public: + DISALLOW_COPY_AND_MOVE(DslmService); + explicit DslmService(int32_t saId, bool runOnCreate); + virtual ~DslmService() = default; + void OnStart() override; + void OnStop() override; + int32_t Dump(int fd, const std::vector &args) override; + int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; + +private: + int32_t ProcessGetDeviceSecurityLevel(MessageParcel &data, MessageParcel &reply); +}; +} // DeviceSecurityLevel +} // Security +} // OHOS + +#endif // DSLM_SERVICE_H \ No newline at end of file diff --git a/test/BUILD.gn b/test/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..a4601f547a019ab0e56f44caab8c05449b662c4b --- /dev/null +++ b/test/BUILD.gn @@ -0,0 +1,68 @@ +# Copyright (C) 2021 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("//build/ohos.gni") +import("//build/test.gni") + +# test unittest +ohos_unittest("dslm_test") { + install_enable = true + testonly = true + part_name = "devicesecuritylevel" + subsystem_name = "security" + module_out_path = "${root_out_dir}/${subsystem_name}/${part_name}" + + sources = [ + "//base/security/devicesecuritylevel/oem_property/ohos/dslm_ohos_credential.c", + "//base/security/devicesecuritylevel/service/sa/common/dslm_rpc_process.c", + "dslm_msg_interface_mock.cpp", + "dslm_request_callback_mock.cpp", + "dslm_test.cpp", + ] + + include_dirs = [ + "//base/security/devicesecuritylevel/common/include", + "//base/security/devicesecuritylevel/interfaces/include", + "//base/security/devicesecuritylevel/service/include", + "//base/security/devicesecuritylevel/service/dslm", + "//base/security/devicesecuritylevel/service/sa/common", + "//base/security/devicesecuritylevel/baselib/msglib/include/", + ] + + deps = [ + "//base/security/devicesecuritylevel/baselib/utils:utils_static", + "//base/security/devicesecuritylevel/oem_property/ohos:dslm_ohos_cread_obj", + "//base/security/devicesecuritylevel/service/bigdata:service_bigdata_obj", + "//base/security/devicesecuritylevel/service/common:service_common_obj", + "//base/security/devicesecuritylevel/service/dslm:service_dslm_test_obj", + "//base/security/devicesecuritylevel/service/msg:service_msg_obj", + "//third_party/googletest:gmock", + ] + + deps += [ "//base/security/devicesecuritylevel/interfaces:dslm_sdk" ] + + external_deps = [ "utils_base:utils" ] + + if (is_standard_system) { + external_deps += [ "hilog_native:libhilog" ] + } + + if (is_large_system) { + external_deps += [ "hilog:libhilog" ] + } + + # cflags = [ "-fsanitize=address" ] + # cflags += [ "-fno-omit-frame-pointer" ] + # cflags += [ "-fsanitize-address-use-after-scope" ] + # ldflags = [ "-fsanitize=address" ] +} diff --git a/test/dslm_msg_interface_mock.cpp b/test/dslm_msg_interface_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e7ddd0ab1b32d2693536f0c74f2d615f9c53681e --- /dev/null +++ b/test/dslm_msg_interface_mock.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2021 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 "dslm_msg_interface_mock.h" + +#include +#include +#include + +using namespace OHOS::Security::DslmUnitTest; +using namespace testing; +using namespace testing::ext; + +extern "C" { +// just for testing +extern Messenger *g_messenger; +extern int32_t OnPeerMsgReceived(const DeviceIdentify *devId, const uint8_t *msg, uint32_t len); +extern int32_t OnSendResultNotifier(const DeviceIdentify *devId, uint64_t transNo, uint32_t result); +extern int32_t OnPeerStatusReceiver(const DeviceIdentify *deviceId, uint32_t status, uint32_t devType); +} + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { +static DslmMsgInterface *GetDslmMsgInterface() +{ + return reinterpret_cast(g_messenger); +} + +DslmMsgInterfaceMock::DslmMsgInterfaceMock() +{ + g_messenger = reinterpret_cast(this); + ON_CALL(*this, IsMessengerReady).WillByDefault(Return(true)); +} + +DslmMsgInterfaceMock::~DslmMsgInterfaceMock() +{ + g_messenger = nullptr; +} + +void DslmMsgInterfaceMock::MakeMsgLoopback() const +{ + auto loopback = [this](const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, + const uint8_t *msg, uint32_t msgLen) { + this->MakeMsgReceivedFrom(devId, msg, msgLen); + return 0; + }; + + ON_CALL(*this, SendMsgTo).WillByDefault(loopback); +} + +void DslmMsgInterfaceMock::MakeSelfDeviceId(const DeviceIdentify *self) const +{ + auto loopback = [this, self](const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) { + *devId = *self; + return true; + }; + + ON_CALL(*this, GetSelfDeviceIdentify).WillByDefault(loopback); +} + +void DslmMsgInterfaceMock::MakeDeviceOnline(const DeviceIdentify *devId) const +{ + OnPeerStatusReceiver(devId, 1, 0); +} + +void DslmMsgInterfaceMock::MakeDeviceOffline(const DeviceIdentify *devId) const +{ + OnPeerStatusReceiver(devId, 0, 0); +} + +void DslmMsgInterfaceMock::MakeMsgReceivedFrom(const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) const +{ + auto msgBuffer = std::make_shared>(msg, msg + msgLen); + std::thread t([devId, msgBuffer]() { OnPeerMsgReceived(devId, msgBuffer->data(), msgBuffer->size()); }); + t.detach(); +} + +extern "C" { +Messenger *CreateMessengerImpl(const MessengerConfig *cfg) +{ + return nullptr; +} + +void DestroyMessengerImpl(Messenger *messenger) +{ + return; +} + +bool IsMessengerReadyImpl(const Messenger *messenger) +{ + return GetDslmMsgInterface()->IsMessengerReady(messenger); +} + +uint64_t SendMsgToImpl(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, const uint8_t *msg, + uint32_t msgLen) +{ + return GetDslmMsgInterface()->SendMsgTo(messenger, transNo, devId, msg, msgLen); +} + +bool GetDeviceOnlineStatusImpl(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType) +{ + return GetDslmMsgInterface()->GetDeviceOnlineStatus(messenger, devId, devType); +} + +bool GetSelfDeviceIdentifyImpl(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) +{ + return GetDslmMsgInterface()->GetSelfDeviceIdentify(messenger, devId, devType); +} + +void ForEachDeviceProcessImpl(const Messenger *messenger, const DeviceProcessor processor, void *para) +{ + return; +} + +bool GetDeviceStatisticInfoImpl(const Messenger *messenger, const DeviceIdentify *devId, StatisticInformation *info) +{ + return true; +} +} +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS diff --git a/test/dslm_msg_interface_mock.h b/test/dslm_msg_interface_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..5bf03ecd6ad3a48b7ec8e2564a1985c6f6ec6376 --- /dev/null +++ b/test/dslm_msg_interface_mock.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2021 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 DSLM_MSG_INTERFACE_MOCK_H +#define DSLM_MSG_INTERFACE_MOCK_H + +#include +#include + +#include "messenger.h" + +#include "dslm_callback_info.h" + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { +class DslmMsgInterface { +public: + DslmMsgInterface() {}; + virtual ~DslmMsgInterface() {}; + + virtual bool IsMessengerReady(const Messenger *messenger) = 0; + + virtual uint64_t SendMsgTo(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, + const uint8_t *msg, uint32_t msgLen) = 0; + + virtual bool GetDeviceOnlineStatus(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType) = 0; + + virtual bool GetSelfDeviceIdentify(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType) = 0; + + virtual void ForEachDeviceProcess(const Messenger *messenger, const DeviceProcessor processor, void *para) = 0; +}; + +class DslmMsgInterfaceMock : public DslmMsgInterface { +public: + DslmMsgInterfaceMock(); + ~DslmMsgInterfaceMock() override; + MOCK_METHOD1(IsMessengerReady, bool(const Messenger *messenger)); + MOCK_METHOD5(SendMsgTo, uint64_t(const Messenger *messenger, uint64_t transNo, const DeviceIdentify *devId, + const uint8_t *msg, uint32_t msgLen)); + MOCK_METHOD3(GetDeviceOnlineStatus, + bool(const Messenger *messenger, const DeviceIdentify *devId, uint32_t *devType)); + MOCK_METHOD3(GetSelfDeviceIdentify, bool(const Messenger *messenger, DeviceIdentify *devId, uint32_t *devType)); + MOCK_METHOD3(ForEachDeviceProcess, void(const Messenger *messenger, const DeviceProcessor processor, void *para)); + void MakeMsgLoopback() const; + void MakeSelfDeviceId(const DeviceIdentify *devId) const; + void MakeDeviceOnline(const DeviceIdentify *devId) const; + void MakeDeviceOffline(const DeviceIdentify *devId) const; + void MakeMsgReceivedFrom(const DeviceIdentify *devId, const uint8_t *msg, uint32_t msgLen) const; +}; + +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS + +#endif // DSLM_MSG_INTERFACE_MOCK_H diff --git a/test/dslm_request_callback_mock.cpp b/test/dslm_request_callback_mock.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a4abac7772234602b05ed360a96c3be2829b9bf4 --- /dev/null +++ b/test/dslm_request_callback_mock.cpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2021 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 "dslm_request_callback_mock.h" + +#include +#include +#include + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { + +DslmRequestCallbackMock::DslmRequestCallbackMock() +{ + std::lock_guard lock(mutex_); + EXPECT_EQ(obj_, nullptr); + obj_ = this; +} + +DslmRequestCallbackMock::~DslmRequestCallbackMock() +{ + std::lock_guard lock(mutex_); + EXPECT_EQ(obj_, this); + obj_ = nullptr; +} + +void DslmRequestCallbackMock::MockedCallback(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info) +{ + std::lock_guard lock(mutex_); + if (obj_ != nullptr) { + obj_->RequestCallback(cookie, result, info); + } +} + +DslmRequestCallback *DslmRequestCallbackMock::obj_ = nullptr; +std::mutex DslmRequestCallbackMock::mutex_ {}; + +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS diff --git a/test/dslm_request_callback_mock.h b/test/dslm_request_callback_mock.h new file mode 100644 index 0000000000000000000000000000000000000000..b3f4485e1455570c4480494418da5be734fac8d8 --- /dev/null +++ b/test/dslm_request_callback_mock.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021 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 DSLM_REQUEST_CALLBACK_MOCK_H +#define DSLM_REQUEST_CALLBACK_MOCK_H + +#include +#include + +#include "messenger.h" + +#include "dslm_callback_info.h" + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { + +class DslmRequestCallback { +public: + DslmRequestCallback() {}; + virtual ~DslmRequestCallback() {}; + virtual void RequestCallback(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info) = 0; +}; + +class DslmRequestCallbackMock : public DslmRequestCallback { +public: + DslmRequestCallbackMock(); + virtual ~DslmRequestCallbackMock() override; + MOCK_METHOD3(RequestCallback, void(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info)); + + static void MockedCallback(uint32_t cookie, uint32_t result, const DslmCallbackInfo *info); + +private: + static DslmRequestCallback *obj_; + static std::mutex mutex_; +}; + +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS + +#endif // DSLM_REQUEST_CALLBACK_MOCK_H diff --git a/test/dslm_test.cpp b/test/dslm_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..87d0f8f1a1338d7f61c86abdc1704302ff7c7d2d --- /dev/null +++ b/test/dslm_test.cpp @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2021 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 "dslm_test.h" + +#include +#include +#include +#include +#include +#include + +#include "securec.h" + +#include "device_security_defines.h" +#include "device_security_info.h" + +#include "dslm_core_defines.h" +#include "dslm_core_process.h" +#include "dslm_credential.h" +#include "dslm_crypto.h" +#include "dslm_device_list.h" +#include "dslm_fsm_process.h" +#include "dslm_messenger_wrapper.h" +#include "dslm_msg_interface_mock.h" +#include "dslm_msg_serialize.h" +#include "dslm_msg_utils.h" +#include "dslm_request_callback_mock.h" + +using namespace std; +using namespace std::chrono; +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { +#ifdef GTEST_INCLUDE_GTEST_GTEST_H_ +void DslmTest::SetUpTestCase() +{ +} +void DslmTest::TearDownTestCase() +{ +} +void DslmTest::SetUp() +{ +} +void DslmTest::TearDown() +{ +} + +static void BlockCheckDeviceStatus(const DeviceIdentify *device, uint32_t status, uint64_t millisec) +{ + static int sleepTick = 10; + uint64_t cnt = millisec / sleepTick + 1; + do { + const DslmDeviceInfo *info = GetDslmDeviceInfo(device); + if (info == nullptr) { + continue; + } + if (info->machine.currState == status) { + break; + } + if (cnt == 0) { + break; + } + this_thread::sleep_for(milliseconds(sleepTick)); + cnt--; + } while (true); +} + +HWTEST_F(DslmTest, BuildDeviceSecInfoRequest_case1, TestSize.Level1) +{ + uint64_t random = 0x0807060504030201; + MessageBuff *msg = nullptr; + // 0d196608 = 0x030000 + const char *except = + "{\"message\":1,\"payload\":{\"version\":196608,\"challenge\":\"0102030405060708\",\"support\":[300]}}"; + + int32_t ret = BuildDeviceSecInfoRequest(random, &msg); + ASSERT_EQ(0, ret); + EXPECT_STREQ(except, (const char *)msg->buff); + FreeMessageBuff(msg); +} + +HWTEST_F(DslmTest, BuildDeviceSecInfoResponse_case1, TestSize.Level1) +{ + uint64_t random = 0x0807060504030201; + uint8_t info[] = {'a', 'b', 'c', 'd', 1, 3, 5, 7, 9}; + DslmCredBuff cred = {(CredType)3, 9, info}; + + // 0d196608 = 0x030000 + const char *except = "{\"message\":2,\"payload\":{\"version\":196608,\"type\":3,\"challenge\":\"0102030405060708\"," + "\"info\":\"YWJjZAEDBQcJ\"}}"; + + MessageBuff *msg = nullptr; + int32_t ret = BuildDeviceSecInfoResponse(random, (DslmCredBuff *)&cred, &msg); + ASSERT_EQ(0, ret); + + EXPECT_STREQ(except, (const char *)msg->buff); + FreeMessageBuff(msg); +} + +HWTEST_F(DslmTest, ParseMessage_case1, TestSize.Level1) +{ + const char *message = "{\"message\":1,\"payload\":{\"version\":131072,\"challenge\":\"0102030405060708\"}}"; + const char *except = "{\"version\":131072,\"challenge\":\"0102030405060708\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + MessagePacket *packet = ParseMessage(&msg); + ASSERT_NE(nullptr, packet); + + EXPECT_EQ(1, (int32_t)packet->type); + EXPECT_STREQ(except, (const char *)packet->payload); + + FreeMessagePacket(packet); +} + +HWTEST_F(DslmTest, ParseMessage_case2, TestSize.Level1) +{ + const char *message = "{\"mege\":1,\"payload\":{\"version\":131072,\"challenge\":\"0102030405060708\"}}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + MessagePacket *packet = ParseMessage(&msg); + EXPECT_EQ(nullptr, packet); + FreeMessagePacket(packet); +} + +HWTEST_F(DslmTest, ParseMessage_case3, TestSize.Level1) +{ + const char *message = "{\"message\":1,\"pay\":{\"version\":131072,\"challenge\":\"0102030405060708\"}}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + MessagePacket *packet = ParseMessage(&msg); + EXPECT_EQ(nullptr, packet); + FreeMessagePacket(packet); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case1, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challenge\":\"010203040a0b0c0d\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + + // 3351057 = 0x332211 + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(0, ret); + + EXPECT_EQ((uint32_t)0x332211, obj.version); + EXPECT_EQ((uint64_t)0x0d0c0b0a04030201, obj.challenge); + EXPECT_EQ((uint32_t)0, obj.arraySize); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case2, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challenge\":\"z\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(ERR_NO_CHALLENGE, ret); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case3, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challenge\":1}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(ERR_NO_CHALLENGE, ret); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case4, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challssenge\":\"z\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(ERR_NO_CHALLENGE, ret); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case5, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challenge\":\"010203040a0b0c0d\",\"support\":[33,44,55]}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + + // 3351057 = 0x332211 + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(0, ret); + EXPECT_EQ((uint32_t)0x332211, obj.version); + EXPECT_EQ((uint64_t)0x0d0c0b0a04030201, obj.challenge); + // add support + EXPECT_EQ((uint32_t)3, obj.arraySize); + EXPECT_EQ((uint32_t)33, obj.credArray[0]); + EXPECT_EQ((uint32_t)44, obj.credArray[1]); + EXPECT_EQ((uint32_t)55, obj.credArray[2]); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoRequest_case6, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challenge\":\"010203040a0b0c0d\",\"support\":[]}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + RequestObject obj; + memset_s(&obj, sizeof(RequestObject), 0, sizeof(RequestObject)); + + // 3351057 = 0x332211 + int32_t ret = ParseDeviceSecInfoRequest(&msg, &obj); + EXPECT_EQ(0, ret); + EXPECT_EQ((uint32_t)0x332211, obj.version); + EXPECT_EQ((uint64_t)0x0d0c0b0a04030201, obj.challenge); + // add support + EXPECT_EQ((uint32_t)0, obj.arraySize); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoResponse_case1, TestSize.Level1) +{ + const char *message = "{\"version\":131072,\"challenge\":\"3C1F21EE53D3C4E2\",\"type\":2,\"info\":" + "\"SkFERS1BTDAwOjg3QUQyOEQzQjFCLi4u\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + uint64_t challenge; + uint32_t version; + DslmCredBuff *cred = nullptr; + + // 131072 = 0x020000 + int32_t ret = ParseDeviceSecInfoResponse(&msg, &challenge, &version, &cred); + EXPECT_EQ(0, ret); + EXPECT_EQ((uint32_t)0x020000, version); + + EXPECT_EQ((uint64_t)0xE2C4D353EE211F3C, challenge); + + const char *except = "JADE-AL00:87AD28D3B1B..."; + EXPECT_NE(nullptr, cred); + EXPECT_EQ(2, (int32_t)cred->type); + EXPECT_EQ(strlen(except), cred->credLen); + EXPECT_EQ(0, strncmp(except, (const char *)cred->credVal, cred->credLen)); + DestroyDslmCred(cred); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoResponse_case2, TestSize.Level1) +{ + const char *message = "{\"version\":3351057,\"challssenge\":\"z\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + uint64_t challenge; + uint32_t ver; + DslmCredBuff *cred = nullptr; + + int32_t ret = ParseDeviceSecInfoResponse(&msg, &challenge, &ver, &cred); + EXPECT_EQ(ERR_NO_CHALLENGE, ret); +} + +HWTEST_F(DslmTest, ParseDeviceSecInfoResponse_case3, TestSize.Level1) +{ + const char *message = + "{\"version\":131072,\"challenge\":\"3C1F21EE53D3C4E2\",\"type\":2,\"infod\":\"JADE-AL00:87AD28D3B1B...\"}"; + + uint32_t messageLen = strlen(message) + 1; + MessageBuff msg = {.length = messageLen, .buff = (uint8_t *)message}; + + uint64_t challenge; + uint32_t ver; + DslmCredBuff *cred = nullptr; + + int32_t ret = ParseDeviceSecInfoResponse(&msg, &challenge, &ver, &cred); + EXPECT_EQ(ERR_NO_CRED, ret); +} + +HWTEST_F(DslmTest, RandomValue_case1, TestSize.Level1) +{ + RandomValue rand1 = {0, {0}}; + memset_s(&rand1, sizeof(RandomValue), 0, sizeof(RandomValue)); + GenerateRandom(&rand1, sizeof(uint64_t)); + + RandomValue rand2 = {0, {0}}; + memset_s(&rand2, sizeof(RandomValue), 0, sizeof(RandomValue)); + GenerateRandom(&rand2, sizeof(uint64_t)); + + EXPECT_EQ(sizeof(uint64_t), rand1.length); + EXPECT_EQ(sizeof(uint64_t), rand2.length); + + EXPECT_GT(rand1.value[0] + rand1.value[1] + rand1.value[2] + rand1.value[3], 0); + EXPECT_EQ(rand1.value[31] + rand1.value[30] + rand1.value[29] + rand1.value[28], 0); + EXPECT_NE(0, memcmp(rand1.value, rand2.value, sizeof(uint64_t))); +} + +HWTEST_F(DslmTest, RandomValue_case2, TestSize.Level1) +{ + RandomValue rand = {0, {0}}; + memset_s(&rand, sizeof(RandomValue), 0, sizeof(RandomValue)); + + GenerateRandom(&rand, 1024); + EXPECT_EQ(RAMDOM_MAX_LEN, (int32_t)rand.length); +} + +HWTEST_F(DslmTest, OhosDslmCred_case1, TestSize.Level1) +{ + const DeviceIdentify identiy = {DEVICE_ID_MAX_LEN, {0}}; + RequestObject object; + + object.arraySize = 1; + object.credArray[0] = CRED_TYPE_STANDARD; + object.challenge = 0x1234567812345678; + object.version = 0x112234; + + DslmCredBuff *cred = nullptr; + + int32_t ret = DefaultRequestDslmCred(&identiy, &object, &cred); + ASSERT_EQ(SUCCESS, (int32_t)ret); + + DslmCredInfo info; + memset_s(&info, sizeof(DslmCredInfo), 0, sizeof(DslmCredInfo)); + + ret = DefaultVerifyDslmCred(&identiy, object.challenge, cred, &info); + EXPECT_EQ(SUCCESS, ret); + EXPECT_GE(info.credLevel, (uint32_t)1); + + DestroyDslmCred(cred); +} + +HWTEST_F(DslmTest, OnRequestDeviceSecLevelInfo_case1, TestSize.Level1) +{ + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'a', 'b', 'c', 'd', 'e', 'f', 'g'}}; + + const RequestOption option = { + .challenge = 0xffffffffffffffff, + .timeout = 3, + }; + + { + uint32_t cookie = 1234; + DslmRequestCallbackMock mockCallback; + EXPECT_CALL(mockCallback, RequestCallback(_, _, _)).Times(Exactly(0)); + int32_t ret = OnRequestDeviceSecLevelInfo(&device, &option, cookie, DslmRequestCallbackMock::MockedCallback); + EXPECT_EQ((int32_t)ret, ERR_MSG_NOT_INIT); + } + + { + uint32_t cookie = 5678; + DslmMsgInterfaceMock mockMsg; + DslmRequestCallbackMock mockCallback; + EXPECT_CALL(mockMsg, IsMessengerReady(_)).Times(AtLeast(1)); + EXPECT_CALL(mockMsg, GetDeviceOnlineStatus(_, _, _)).Times(AtLeast(1)).WillRepeatedly(Return(false)); + EXPECT_CALL(mockCallback, RequestCallback(_, _, _)).Times(Exactly(0)); + int32_t ret = OnRequestDeviceSecLevelInfo(&device, &option, cookie, DslmRequestCallbackMock::MockedCallback); + EXPECT_EQ((int32_t)ret, ERR_NOEXIST_DEVICE); + + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, _, _)).Times(AtLeast(2)); + mockMsg.MakeMsgLoopback(); + mockMsg.MakeDeviceOnline(&device); + BlockCheckDeviceStatus(&device, STATE_SUCCESS, 10000); + mockMsg.MakeDeviceOffline(&device); + } + + { + uint32_t cookie = 0xabcd; + DslmMsgInterfaceMock mockMsg; + EXPECT_CALL(mockMsg, IsMessengerReady(_)).Times(AtLeast(1)); + EXPECT_CALL(mockMsg, GetDeviceOnlineStatus(_, _, _)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, _, _)).Times(Exactly(1)); + DslmRequestCallbackMock mockCallback; + auto IsRightLevel = [](const DslmCallbackInfo *info) { return info->level >= 1; }; + EXPECT_CALL(mockCallback, RequestCallback(cookie, 0, Truly(IsRightLevel))).Times(Exactly(1)); + + int32_t ret = OnRequestDeviceSecLevelInfo(&device, &option, cookie, DslmRequestCallbackMock::MockedCallback); + EXPECT_EQ(ret, (int32_t)0); + mockMsg.MakeDeviceOffline(&device); + } +} + +HWTEST_F(DslmTest, OnRequestDeviceSecLevelInfo_case2, TestSize.Level1) +{ + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'a'}}; + const RequestOption option = { + .challenge = 0xffabcdffffffffee, + .timeout = 3, + .extra = 0, + }; + + DslmMsgInterfaceMock mockMsg; + EXPECT_CALL(mockMsg, IsMessengerReady(_)).Times(AtLeast(1)); + EXPECT_CALL(mockMsg, GetDeviceOnlineStatus(_, _, _)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + auto isSendRequestOut = [](const uint8_t *message) { + const char *prefix = "{\"message\":1,\"payload\":{\"version\":196608,\"challenge\":\""; + string msg = string((char *)message); + EXPECT_EQ((int)msg.rfind(prefix, 0), 0); + return true; + }; + + uint32_t cookie = 0x4567; + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, Truly(isSendRequestOut), _)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + int32_t ret = OnRequestDeviceSecLevelInfo(&device, &option, cookie, DslmRequestCallbackMock::MockedCallback); + EXPECT_EQ((int32_t)ret, (int32_t)0); + mockMsg.MakeDeviceOffline(&device); +} + +HWTEST_F(DslmTest, OnRequestDeviceSecLevelInfo_case3, TestSize.Level1) +{ + DslmMsgInterfaceMock mockMsg; + DslmRequestCallbackMock mockCallback; + + EXPECT_CALL(mockMsg, IsMessengerReady(_)).Times(AtLeast(1)); + EXPECT_CALL(mockMsg, GetDeviceOnlineStatus(_, _, _)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, _, _)).Times(AtLeast(1)).WillRepeatedly(Return(true)); + + mutex mtx; + condition_variable cv; + int32_t cnt = 0; + const time_point start = system_clock::now(); + const int32_t reqTimes = 3; + + uint32_t cookies[] = {0, 0x1234, 0x5678, 0xabcd}; + uint32_t timeouts[] = {0, 1, 5, 9}; + + auto checkCookie = [&mtx, &cv, &cnt, &start, &cookies, &timeouts](uint32_t cookie) { + unique_lock lck(mtx); + cnt++; + cv.notify_one(); + time_point curr = system_clock::now(); + auto cost = duration_cast(curr - start).count(); + EXPECT_EQ(cookie, cookies[cnt]); + EXPECT_EQ(cost, timeouts[cnt]); + return true; + }; + + EXPECT_CALL(mockCallback, RequestCallback(Truly(checkCookie), ERR_TIMEOUT, _)).Times(Exactly(3)); + + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'a', 'b', 'c', 'd', 'e', 'f', 'a', 'b'}}; + RequestOption option; + for (int i = 1; i <= reqTimes; i++) { + option.timeout = timeouts[i]; + int32_t ret = + OnRequestDeviceSecLevelInfo(&device, &option, cookies[i], DslmRequestCallbackMock::MockedCallback); + EXPECT_EQ((int32_t)ret, (int32_t)0); + } + + unique_lock lck(mtx); + cv.wait(lck, [&cnt]() { return (cnt == reqTimes); }); + mockMsg.MakeDeviceOffline(&device); +} + +HWTEST_F(DslmTest, OnPeerMsgRequestInfoReceived_case1, TestSize.Level1) +{ + const char *input = "{\"version\":65536,\"challenge\":\"0102030405060708\"}"; + uint32_t len = strlen(input) + 1; + + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}; + + DslmMsgInterfaceMock mockMsg; + + auto isSendResponseOut = [](const uint8_t *message) { + const string msg = string((char *)message); + EXPECT_EQ((int)msg.find("{\"message\":2,\"payload\":{"), 0); + EXPECT_GT((int)msg.find("\"version\":"), 0); + EXPECT_GT((int)msg.find("\"challenge\":"), 0); + EXPECT_GT((int)msg.find("\"type\":"), 0); + EXPECT_GT((int)msg.find("\"info\":"), 0); + return true; + }; + + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, Truly(isSendResponseOut), _)).Times(Exactly(1)); + + int32_t ret = OnPeerMsgRequestInfoReceived(&device, (const uint8_t *)input, len); + EXPECT_EQ(0, (int32_t)ret); +} + +HWTEST_F(DslmTest, OnPeerMsgResponseInfoReceived_case2, TestSize.Level1) +{ + const char *input = "{\"version\":65536,\"type\":0,\"challenge\":\"EEFFFFFFFFCDABFF\",\"info\":" + "\"MDAwMTAyMDMwNDA1MDYwNzA4MDkwQTBCMEMwRDBFMEYxMDExMTIxMzE0MTUxNkFBQkJDQ0RE\"}"; + uint32_t len = strlen(input) + 1; + + DeviceIdentify device = {8, {'a', 'b', 'c', 'd', 'e', 'f', 'g'}}; + + int32_t ret = OnPeerMsgResponseInfoReceived(&device, (const uint8_t *)input, len); + EXPECT_EQ(ERR_NOEXIST_DEVICE, (int32_t)ret); +} + +HWTEST_F(DslmTest, InitSelfDeviceSecureLevel_case1, TestSize.Level1) +{ + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'}}; + DslmDeviceInfo *info = GetDslmDeviceInfo(&device); + EXPECT_EQ(nullptr, info); + + DslmMsgInterfaceMock mockMsg; + mockMsg.MakeSelfDeviceId(&device); + mockMsg.MakeMsgLoopback(); + EXPECT_CALL(mockMsg, GetSelfDeviceIdentify(_, _, _)).Times(AtLeast(1)); + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, _, _)).Times(AtLeast(1)); + InitSelfDeviceSecureLevel(); + + info = GetDslmDeviceInfo(&device); + ASSERT_NE(nullptr, info); + + BlockCheckDeviceStatus(&device, STATE_SUCCESS, 10000); + EXPECT_GE(info->credInfo.credLevel, (uint32_t)1); + mockMsg.MakeDeviceOffline(&device); +} + +HWTEST_F(DslmTest, InitSelfDeviceSecureLevel_case2, TestSize.Level1) +{ + const DeviceIdentify device = {DEVICE_ID_MAX_LEN, {'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x'}}; + + DslmDeviceInfo *info = GetDslmDeviceInfo(&device); + EXPECT_EQ(nullptr, info); + + DslmMsgInterfaceMock mockMsg; + EXPECT_CALL(mockMsg, SendMsgTo(_, _, _, _, _)).Times(Exactly(6)); + mockMsg.MakeDeviceOnline(&device); + + info = GetDslmDeviceInfo(&device); + ASSERT_NE(nullptr, info); + EXPECT_EQ((uint32_t)1, info->queryTimes); + EXPECT_EQ((uint32_t)STATE_WAITING_CRED_RSP, info->machine.currState); + + BlockCheckDeviceStatus(&device, STATE_SUCCESS, 5000); + EXPECT_EQ((uint32_t)STATE_FAILED, info->machine.currState); + EXPECT_LT((uint32_t)5, info->queryTimes); + mockMsg.MakeDeviceOffline(&device); +} + +HWTEST_F(DslmTest, InnerKitsTest_case1, TestSize.Level1) +{ + + DeviceIdentify device = {DEVICE_ID_MAX_LEN, {0}}; + + DeviceSecurityInfo *info = NULL; + int32_t ret = RequestDeviceSecurityInfo(&device, NULL, &info); + EXPECT_EQ(ret, 0); + int32_t level = 0; + ret = GetDeviceSecurityLevelValue(info, &level); + FreeDeviceSecurityInfo(info); + EXPECT_EQ(ret, 0); + EXPECT_GE(level, 1); +} + +static int32_t g_cnt = 0; +static mutex g_mtx; +static condition_variable g_cv; + +void TestDeviceSecurityInfoCallback(const DeviceIdentify *identify, struct DeviceSecurityInfo *info) +{ + unique_lock lck(g_mtx); + int32_t level = 0; + int32_t ret = GetDeviceSecurityLevelValue(info, &level); + FreeDeviceSecurityInfo(info); + EXPECT_EQ(ret, 0); + EXPECT_GE(level, 1); + g_cnt++; + g_cv.notify_one(); +} + +HWTEST_F(DslmTest, InnerKitsTest_case2, TestSize.Level1) +{ + + DeviceIdentify device = {DEVICE_ID_MAX_LEN, {0}}; + + g_cnt = 0; + int ret = RequestDeviceSecurityInfoAsync(&device, NULL, TestDeviceSecurityInfoCallback); + EXPECT_EQ(ret, 0); + + ret = RequestDeviceSecurityInfoAsync(&device, NULL, TestDeviceSecurityInfoCallback); + EXPECT_EQ(ret, 0); + + ret = RequestDeviceSecurityInfoAsync(&device, NULL, TestDeviceSecurityInfoCallback); + EXPECT_EQ(ret, 0); + + unique_lock lck(g_mtx); + g_cv.wait_for(lck, std::chrono::milliseconds(2000), []() { return (g_cnt == 3); }); + EXPECT_EQ(g_cnt, 3); +} + +#endif +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS diff --git a/test/dslm_test.h b/test/dslm_test.h new file mode 100644 index 0000000000000000000000000000000000000000..28558761b7c991401c5f2e1e122e5b50d7cb3c30 --- /dev/null +++ b/test/dslm_test.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 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 DSLM_UNIT_TEST_H +#define DSLM_UNIT_TEST_H + +#include + +namespace OHOS { +namespace Security { +namespace DslmUnitTest { +using namespace testing::ext; +class DslmTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; +} // namespace DslmUnitTest +} // namespace Security +} // namespace OHOS + + +#endif // DSLM_UNIT_TEST_H