1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "device_security_info.h"
17 
18 #include <future>
19 
20 #include "hilog/log.h"
21 
22 #include "device_security_level_callback_helper.h"
23 #include "device_security_level_callback_stub.h"
24 #include "device_security_level_defines.h"
25 #include "device_security_level_loader.h"
26 #include "device_security_level_proxy.h"
27 
28 using namespace OHOS::HiviewDFX;
29 using namespace OHOS::Security::DeviceSecurityLevel;
30 
RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify * identify,const RequestOption * option,const ResultCallback & callback)31 static int32_t RequestDeviceSecurityInfoAsyncImpl(const DeviceIdentify *identify, const RequestOption *option,
32     const ResultCallback &callback)
33 {
34     if (identify == nullptr || callback == nullptr) {
35         HILOG_ERROR(LOG_CORE, "GetDeviceSecurityInfo input error.");
36         return ERR_INVALID_PARA;
37     }
38 
39     constexpr uint32_t defaultKeepLen = 45;
40     constexpr uint32_t maxKeepLen = 300;
41     static RequestOption defaultOption = {0, defaultKeepLen, 0};
42     if (option == nullptr) {
43         option = &defaultOption;
44     }
45     if (option->timeout > maxKeepLen) {
46         HILOG_ERROR(LOG_CORE, "GetDeviceSecurityInfo input error, timeout too len.");
47         return ERR_INVALID_PARA;
48     }
49     auto object = DeviceSecurityLevelLoader::GetInstance().LoadDslmService();
50     auto proxy = iface_cast<DeviceSecurityLevelProxy>(object);
51     if (proxy == nullptr) {
52         HILOG_ERROR(LOG_CORE, "GetDeviceSecurityInfo iface_cast error.");
53         return ERR_IPC_REMOTE_OBJ_ERR;
54     }
55     auto &helper = DelayedRefSingleton<DeviceSecurityLevelCallbackHelper>::GetInstance();
56     sptr<DeviceSecurityLevelCallbackStub> stub = nullptr;
57     uint32_t cookie = 0;
58 
59     auto success = helper.Publish(*identify, callback, option->timeout, stub, cookie);
60     if (!success || stub == nullptr || cookie == 0) {
61         HILOG_ERROR(LOG_CORE, "GetDeviceSecurityInfo get stub error.");
62         return ERR_REG_CALLBACK;
63     }
64 
65     auto result = proxy->RequestDeviceSecurityLevel(*identify, *option, stub->AsObject(), cookie);
66     if (result != SUCCESS) {
67         HILOG_ERROR(LOG_CORE, "GetDeviceSecurityInfo RequestDeviceSecurityLevel error.");
68         helper.Withdraw(cookie);
69         return result;
70     }
71 
72     return SUCCESS;
73 }
74 
RequestDeviceSecurityInfoImpl(const DeviceIdentify * identify,const RequestOption * option,DeviceSecurityInfo ** info)75 static int32_t RequestDeviceSecurityInfoImpl(const DeviceIdentify *identify, const RequestOption *option,
76     DeviceSecurityInfo **info)
77 {
78     std::promise<DeviceSecurityInfo *> promise;
79 
80     auto callback = [&promise](const DeviceIdentify *identify, struct DeviceSecurityInfo *info) {
81         promise.set_value(info);
82         return;
83     };
84     auto result = RequestDeviceSecurityInfoAsyncImpl(identify, option, callback);
85     if (result != SUCCESS) {
86         HILOG_ERROR(LOG_CORE, "RequestDeviceSecurityInfoImpl RequestDeviceSecurityLevel error.");
87         return result;
88     }
89     *info = promise.get_future().get();
90     return SUCCESS;
91 }
92 
FreeDeviceSecurityInfoImpl(DeviceSecurityInfo * info)93 static void FreeDeviceSecurityInfoImpl(DeviceSecurityInfo *info)
94 {
95     if (info != nullptr && info->magicNum == SECURITY_MAGIC) {
96         info->magicNum = 0;
97         delete info;
98     }
99 }
100 
GetDeviceSecurityLevelValueImpl(const DeviceSecurityInfo * info,int32_t * level)101 static int32_t GetDeviceSecurityLevelValueImpl(const DeviceSecurityInfo *info, int32_t *level)
102 {
103     if (info == nullptr || level == nullptr) {
104         return ERR_INVALID_PARA;
105     }
106     if (info->magicNum != SECURITY_MAGIC) {
107         return ERR_INVALID_PARA;
108     }
109 
110     *level = static_cast<int32_t>(info->level);
111     return static_cast<int32_t>(info->result);
112 }
113 
114 #ifdef __cplusplus
115 extern "C" {
116 #endif
117 
RequestDeviceSecurityInfo(const DeviceIdentify * identify,const RequestOption * option,DeviceSecurityInfo ** info)118 int32_t RequestDeviceSecurityInfo(const DeviceIdentify *identify, const RequestOption *option,
119     DeviceSecurityInfo **info)
120 {
121     return RequestDeviceSecurityInfoImpl(identify, option, info);
122 }
123 
RequestDeviceSecurityInfoAsync(const DeviceIdentify * identify,const RequestOption * option,DeviceSecurityInfoCallback callback)124 int32_t RequestDeviceSecurityInfoAsync(const DeviceIdentify *identify, const RequestOption *option,
125     DeviceSecurityInfoCallback callback)
126 {
127     return RequestDeviceSecurityInfoAsyncImpl(identify, option, callback);
128 }
129 
FreeDeviceSecurityInfo(DeviceSecurityInfo * info)130 void FreeDeviceSecurityInfo(DeviceSecurityInfo *info)
131 {
132     return FreeDeviceSecurityInfoImpl(info);
133 }
134 
GetDeviceSecurityLevelValue(const DeviceSecurityInfo * info,int32_t * level)135 int32_t GetDeviceSecurityLevelValue(const DeviceSecurityInfo *info, int32_t *level)
136 {
137     return GetDeviceSecurityLevelValueImpl(info, level);
138 }
139 
140 #ifdef __cplusplus
141 }
142 #endif
143