1 /*
2 * Copyright (C) 2021-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_auth.h"
17
18 #include "alg_loader.h"
19 #include "callback_manager.h"
20 #include "channel_manager.h"
21 #include "common_defs.h"
22 #include "dev_auth_module_manager.h"
23 #include "group_auth_manager.h"
24 #include "group_manager.h"
25 #include "hc_init_protection.h"
26 #include "hc_log.h"
27 #include "json_utils.h"
28 #include "os_account_adapter.h"
29 #include "session_manager.h"
30 #include "task_manager.h"
31
32 static GroupAuthManager *g_groupAuthManager = NULL;
33 static DeviceGroupManager *g_groupManagerInstance = NULL;
34
DestroyGroupAuthTask(HcTaskBase * task)35 static void DestroyGroupAuthTask(HcTaskBase *task)
36 {
37 AuthDeviceTask *realTask = (AuthDeviceTask *)task;
38 FreeJson(realTask->authParams);
39 }
40
InitAuthDeviceTask(int32_t osAccountId,AuthDeviceTask * task,int64_t authReqId,CJson * authParams,const DeviceAuthCallback * gaCallback)41 static bool InitAuthDeviceTask(int32_t osAccountId, AuthDeviceTask *task, int64_t authReqId, CJson *authParams,
42 const DeviceAuthCallback *gaCallback)
43 {
44 task->base.doAction = DoAuthDevice;
45 task->base.destroy = DestroyGroupAuthTask;
46 task->authReqId = authReqId;
47 if (AddByteToJson(authParams, FIELD_REQUEST_ID, (const uint8_t*)&authReqId, sizeof(int64_t)) != HC_SUCCESS) {
48 LOGE("Failed to add requestId to json!");
49 return false;
50 }
51 if (AddIntToJson(authParams, FIELD_OS_ACCOUNT_ID, osAccountId) != HC_SUCCESS) {
52 LOGE("Failed to add os accountId to json for auth device!");
53 return false;
54 }
55 task->authParams = authParams;
56 task->callback = gaCallback;
57 if (task->callback == NULL) {
58 LOGE("The input auth callback is null!");
59 return false;
60 }
61 return true;
62 }
63
InitProcessDataTask(AuthDeviceTask * task,int64_t authReqId,CJson * receivedData,const DeviceAuthCallback * gaCallback)64 static bool InitProcessDataTask(AuthDeviceTask *task, int64_t authReqId,
65 CJson *receivedData, const DeviceAuthCallback *gaCallback)
66 {
67 task->base.doAction = DoProcessAuthData;
68 task->base.destroy = DestroyGroupAuthTask;
69 task->authReqId = authReqId;
70 if (AddByteToJson(receivedData, FIELD_REQUEST_ID, (const uint8_t*)&authReqId, sizeof(int64_t)) != HC_SUCCESS) {
71 LOGE("Failed to add requestId to json!");
72 return false;
73 }
74 if (AddIntToJson(receivedData, FIELD_OPERATION_CODE, AUTHENTICATE) != HC_SUCCESS) {
75 LOGE("Failed to add operation code to json!");
76 return false;
77 }
78 task->authParams = receivedData;
79 task->callback = gaCallback;
80 if (task->callback == NULL) {
81 LOGE("The input auth callback is null!");
82 return false;
83 }
84 return true;
85 }
86
AuthDevice(int32_t osAccountId,int64_t authReqId,const char * authParams,const DeviceAuthCallback * gaCallback)87 static int32_t AuthDevice(int32_t osAccountId, int64_t authReqId, const char *authParams,
88 const DeviceAuthCallback *gaCallback)
89 {
90 LOGI("Begin AuthDevice. [requestId]:%" PRId64, authReqId);
91 osAccountId = DevAuthGetRealOsAccountLocalId(osAccountId);
92 if ((authParams == NULL) || (osAccountId == INVALID_OS_ACCOUNT)) {
93 LOGE("The input auth params is invalid!");
94 return HC_ERR_INVALID_PARAMS;
95 }
96 CJson *jsonParams = CreateJsonFromString(authParams);
97 if (jsonParams == NULL) {
98 LOGE("Create json from params failed!");
99 return HC_ERR_JSON_FAIL;
100 }
101 AuthDeviceTask *task = (AuthDeviceTask *)HcMalloc(sizeof(AuthDeviceTask), 0);
102 if (task == NULL) {
103 FreeJson(jsonParams);
104 LOGE("Failed to allocate memory for task!");
105 return HC_ERR_ALLOC_MEMORY;
106 }
107 if (!InitAuthDeviceTask(osAccountId, task, authReqId, jsonParams, gaCallback)) {
108 LOGE("Failed to init task!");
109 FreeJson(jsonParams);
110 HcFree(task);
111 return HC_ERR_INIT_TASK_FAIL;
112 }
113 if (PushTask((HcTaskBase*)task) != HC_SUCCESS) {
114 FreeJson(jsonParams);
115 HcFree(task);
116 return HC_ERR_INIT_TASK_FAIL;
117 }
118 LOGI("Push AuthDevice task successfully.");
119 return HC_SUCCESS;
120 }
121
ProcessData(int64_t authReqId,const uint8_t * data,uint32_t dataLen,const DeviceAuthCallback * gaCallback)122 static int32_t ProcessData(int64_t authReqId, const uint8_t *data, uint32_t dataLen,
123 const DeviceAuthCallback *gaCallback)
124 {
125 LOGI("[GA] Begin ProcessData. [requestId]:%" PRId64, authReqId);
126 if ((data == NULL) || (dataLen > MAX_DATA_BUFFER_SIZE)) {
127 LOGE("Invalid input for ProcessData!");
128 return HC_ERR_INVALID_PARAMS;
129 }
130 CJson *receivedData = CreateJsonFromString((const char *)data);
131 if (receivedData == NULL) {
132 LOGE("Create Json for input data failed!");
133 return HC_ERR_JSON_FAIL;
134 }
135 AuthDeviceTask *task = (AuthDeviceTask *)HcMalloc(sizeof(AuthDeviceTask), 0);
136 if (task == NULL) {
137 FreeJson(receivedData);
138 LOGE("Failed to allocate memory for task!");
139 return HC_ERR_ALLOC_MEMORY;
140 }
141 if (!InitProcessDataTask(task, authReqId, receivedData, gaCallback)) {
142 LOGE("Failed to init task!");
143 FreeJson(receivedData);
144 HcFree(task);
145 return HC_ERR_INIT_TASK_FAIL;
146 }
147 if (PushTask((HcTaskBase*)task) != HC_SUCCESS) {
148 FreeJson(receivedData);
149 HcFree(task);
150 return HC_ERR_INIT_TASK_FAIL;
151 }
152 LOGI("Push ProcessData task successfully.");
153 return HC_SUCCESS;
154 }
155
DoCancelAuthRequest(HcTaskBase * task)156 static void DoCancelAuthRequest(HcTaskBase *task)
157 {
158 if (task == NULL) {
159 LOGE("The input task is null!");
160 return;
161 }
162 AuthCancelTask *realTask = (AuthCancelTask *)task;
163 DestroySessionByType(realTask->reqId, realTask->appId, TYPE_CANCEL_AUTH);
164 }
165
DestroyAuthCancelTask(HcTaskBase * task)166 static void DestroyAuthCancelTask(HcTaskBase *task)
167 {
168 if (task == NULL) {
169 LOGE("The input task is null!");
170 return;
171 }
172 AuthCancelTask *realTask = (AuthCancelTask *)task;
173 HcFree(realTask->appId);
174 }
175
CancelAuthRequest(int64_t requestId,const char * appId)176 static void CancelAuthRequest(int64_t requestId, const char *appId)
177 {
178 if (appId == NULL) {
179 LOGE("Invalid app id!");
180 return;
181 }
182 uint32_t appIdLen = HcStrlen(appId) + 1;
183 char *copyAppId = (char *)HcMalloc(appIdLen, 0);
184 if (copyAppId == NULL) {
185 LOGE("Failed to allocate copyAppId memory!");
186 return;
187 }
188 if (strcpy_s(copyAppId, appIdLen, appId) != EOK) {
189 LOGE("Failed to copy appId!");
190 HcFree(copyAppId);
191 return;
192 }
193 AuthCancelTask *task = (AuthCancelTask *)HcMalloc(sizeof(AuthCancelTask), 0);
194 if (task == NULL) {
195 LOGE("Failed to allocate auth cancel task memory!");
196 HcFree(copyAppId);
197 return;
198 }
199 task->base.doAction = DoCancelAuthRequest;
200 task->base.destroy = DestroyAuthCancelTask;
201 task->reqId = requestId;
202 task->appId = copyAppId;
203 if (PushTask((HcTaskBase *)task) != HC_SUCCESS) {
204 HcFree(copyAppId);
205 HcFree(task);
206 }
207 }
208
AllocGmAndGa(void)209 static int32_t AllocGmAndGa(void)
210 {
211 if (g_groupManagerInstance == NULL) {
212 g_groupManagerInstance = (DeviceGroupManager *)HcMalloc(sizeof(DeviceGroupManager), 0);
213 if (g_groupManagerInstance == NULL) {
214 LOGE("Failed to allocate groupManager Instance memory!");
215 return HC_ERR_ALLOC_MEMORY;
216 }
217 }
218 if (g_groupAuthManager == NULL) {
219 g_groupAuthManager = (GroupAuthManager *)HcMalloc(sizeof(GroupAuthManager), 0);
220 if (g_groupAuthManager == NULL) {
221 LOGE("Failed to allocate groupAuth Instance memory!");
222 HcFree(g_groupManagerInstance);
223 g_groupManagerInstance = NULL;
224 return HC_ERR_ALLOC_MEMORY;
225 }
226 }
227 return HC_SUCCESS;
228 }
229
DestroyGmAndGa(void)230 static void DestroyGmAndGa(void)
231 {
232 if (g_groupAuthManager != NULL) {
233 HcFree(g_groupAuthManager);
234 g_groupAuthManager = NULL;
235 }
236 if (g_groupManagerInstance != NULL) {
237 HcFree(g_groupManagerInstance);
238 g_groupManagerInstance = NULL;
239 }
240 }
241
InitAllModules(void)242 static int32_t InitAllModules(void)
243 {
244 int32_t res = GetLoaderInstance()->initAlg();
245 if (res != HC_SUCCESS) {
246 LOGE("[End]: [Service]: Failed to init algorithm module!");
247 return res;
248 }
249 res = InitModules();
250 if (res != HC_SUCCESS) {
251 LOGE("[End]: [Service]: Failed to init all authenticator modules!");
252 return res;
253 }
254 res = InitCallbackManager();
255 if (res != HC_SUCCESS) {
256 LOGE("[End]: [Service]: Failed to init callback manage module!");
257 goto CLEAN_MODULE;
258 }
259 res = InitGroupManager();
260 if (res != HC_SUCCESS) {
261 goto CLEAN_CALLBACK;
262 }
263 InitSessionManager();
264 res = InitTaskManager();
265 if (res != HC_SUCCESS) {
266 LOGE("[End]: [Service]: Failed to init worker thread!");
267 goto CLEAN_ALL;
268 }
269 return res;
270 CLEAN_ALL:
271 DestroySessionManager();
272 DestroyGroupManager();
273 CLEAN_CALLBACK:
274 DestroyCallbackManager();
275 CLEAN_MODULE:
276 DestroyModules();
277 return res;
278 }
279
InitDeviceAuthService(void)280 DEVICE_AUTH_API_PUBLIC int InitDeviceAuthService(void)
281 {
282 LOGI("[Service]: Start to init device auth service!");
283 if (CheckInit() == FINISH_INIT) {
284 LOGI("[End]: [Service]: Device auth service is running!");
285 return HC_SUCCESS;
286 }
287 int32_t res = AllocGmAndGa();
288 if (res != HC_SUCCESS) {
289 return res;
290 }
291 res = InitAllModules();
292 if (res != HC_SUCCESS) {
293 DestroyGmAndGa();
294 return res;
295 }
296 SetInitStatus();
297 LOGI("[End]: [Service]: Init device auth service successfully!");
298 return HC_SUCCESS;
299 }
300
DestroyDeviceAuthService(void)301 DEVICE_AUTH_API_PUBLIC void DestroyDeviceAuthService(void)
302 {
303 LOGI("[Service]: Start to destroy device auth service!");
304 if (CheckDestroy() == FINISH_DESTROY) {
305 LOGI("[End]: [Service]: The service has not been initialized!");
306 return;
307 }
308 DestroyTaskManager();
309 DestroyGroupManager();
310 DestroySessionManager();
311 DestroyGmAndGa();
312 DestroyModules();
313 DestroyChannelManager();
314 DestroyCallbackManager();
315 SetDeInitStatus();
316 LOGI("[End]: [Service]: Destroy device auth service successfully!");
317 }
318
GetGmInstance(void)319 DEVICE_AUTH_API_PUBLIC const DeviceGroupManager *GetGmInstance(void)
320 {
321 if (g_groupManagerInstance == NULL) {
322 LOGE("Service not init.");
323 return NULL;
324 }
325
326 g_groupManagerInstance->regCallback = RegGroupManagerCallback;
327 g_groupManagerInstance->unRegCallback = UnRegGroupManagerCallback;
328 g_groupManagerInstance->regDataChangeListener = RegListenerImpl;
329 g_groupManagerInstance->unRegDataChangeListener = UnRegListenerImpl;
330 g_groupManagerInstance->createGroup = CreateGroupImpl;
331 g_groupManagerInstance->deleteGroup = DeleteGroupImpl;
332 g_groupManagerInstance->addMemberToGroup = AddMemberToGroupImpl;
333 g_groupManagerInstance->deleteMemberFromGroup = DeleteMemberFromGroupImpl;
334 g_groupManagerInstance->addMultiMembersToGroup = AddMultiMembersToGroupImpl;
335 g_groupManagerInstance->delMultiMembersFromGroup = DelMultiMembersFromGroupImpl;
336 g_groupManagerInstance->processData = ProcessBindDataImpl;
337 g_groupManagerInstance->getRegisterInfo = GetRegisterInfo;
338 g_groupManagerInstance->checkAccessToGroup = CheckAccessToGroupImpl;
339 g_groupManagerInstance->getPkInfoList = GetPkInfoListImpl;
340 g_groupManagerInstance->getGroupInfoById = GetGroupInfoByIdImpl;
341 g_groupManagerInstance->getGroupInfo = GetGroupInfoImpl;
342 g_groupManagerInstance->getJoinedGroups = GetJoinedGroupsImpl;
343 g_groupManagerInstance->getRelatedGroups = GetRelatedGroupsImpl;
344 g_groupManagerInstance->getDeviceInfoById = GetDeviceInfoByIdImpl;
345 g_groupManagerInstance->getTrustedDevices = GetTrustedDevicesImpl;
346 g_groupManagerInstance->isDeviceInGroup = IsDeviceInGroupImpl;
347 g_groupManagerInstance->cancelRequest = CancelRequestImpl;
348 g_groupManagerInstance->destroyInfo = DestroyInfoImpl;
349 return g_groupManagerInstance;
350 }
351
GetGaInstance(void)352 DEVICE_AUTH_API_PUBLIC const GroupAuthManager *GetGaInstance(void)
353 {
354 if (g_groupAuthManager == NULL) {
355 LOGE("Service not init.");
356 return NULL;
357 }
358
359 g_groupAuthManager->processData = ProcessData;
360 g_groupAuthManager->authDevice = AuthDevice;
361 g_groupAuthManager->cancelRequest = CancelAuthRequest;
362 return g_groupAuthManager;
363 }
364