1 /*
2  * Copyright (C) 2022-2023 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 "account_module.h"
17 #include "account_auth_plugin_proxy.h"
18 #include "account_module_defines.h"
19 #include "account_multi_task_manager.h"
20 #include "account_version_util.h"
21 #include "alg_loader.h"
22 #include "common_defs.h"
23 #include "device_auth_defines.h"
24 #include "hc_log.h"
25 #include "json_utils.h"
26 #include "pake_v2_auth_client_task.h"
27 #include "pake_v2_auth_server_task.h"
28 
29 #define ACCOUNT_CLIENT_FIRST_MESSAGE 0x0000
30 #define ACCOUNT_CLIENT_STEP_MASK 0x000F
31 
32 typedef struct {
33     AuthModuleBase base;
34 } AccountModule;
35 
IsAccountMsgNeedIgnore(const CJson * in)36 static bool IsAccountMsgNeedIgnore(const CJson *in)
37 {
38     int32_t opCode;
39     if (GetIntFromJson(in, FIELD_OPERATION_CODE, &opCode) != HC_SUCCESS) {
40         LOGE("Get opCode failed.");
41         return true;
42     }
43     const char *key = NULL;
44     if (opCode == OP_BIND) {
45         key = FIELD_MESSAGE;
46     } else if (opCode == AUTHENTICATE) {
47         key = FIELD_STEP;
48     } else {
49         LOGE("Invalid opCode: %d.", opCode);
50         return true;
51     }
52     uint32_t message;
53     if (GetIntFromJson(in, key, (int32_t *)&message) == HC_SUCCESS) {
54         if ((message & ACCOUNT_CLIENT_STEP_MASK) != ACCOUNT_CLIENT_FIRST_MESSAGE) {
55             LOGI("The message is repeated, ignore it, code: %u", message);
56             return true;
57         }
58     }
59     return false;
60 }
61 
CreateAccountTask(int32_t * taskId,const CJson * in,CJson * out)62 static int CreateAccountTask(int32_t *taskId, const CJson *in, CJson *out)
63 {
64     if (taskId == NULL || in == NULL || out == NULL) {
65         LOGE("Params is null in account task.");
66         return HC_ERR_NULL_PTR;
67     }
68     if (IsAccountMsgNeedIgnore(in)) {
69         return HC_ERR_IGNORE_MSG;
70     }
71     if (HasAccountAuthPlugin() == HC_SUCCESS) {
72         return CreateAuthSession(taskId, in, out);
73     }
74     AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
75     if (authManager == NULL) {
76         LOGE("Get multi auth manager instance failed.");
77         return HC_ERROR;
78     }
79     if (authManager->isTaskNumUpToMax() == true) {
80         LOGE("Account auth task is full.");
81         return HC_ERR_ACCOUNT_TASK_IS_FULL;
82     }
83     AccountTask *newTask = CreateAccountTaskT(taskId, in, out);
84     if (newTask == NULL) {
85         LOGE("Create account related task failed.");
86         return HC_ERR_ALLOC_MEMORY;
87     }
88     int32_t res = authManager->addTaskToManager(newTask);
89     if (res != HC_SUCCESS) {
90         LOGE("Add new task into task manager failed, res: %d.", res);
91         newTask->destroyTask(newTask);
92     }
93     return res;
94 }
95 
ProcessAccountTask(int32_t taskId,const CJson * in,CJson * out,int32_t * status)96 static int ProcessAccountTask(int32_t taskId, const CJson *in, CJson *out, int32_t *status)
97 {
98     if (HasAccountAuthPlugin() == HC_SUCCESS) {
99         return ProcessAuthSession(&taskId, in, out, status);
100     }
101     AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
102     if (authManager == NULL) {
103         LOGE("Get multi auth manager instance failed.");
104         return HC_ERROR;
105     }
106     AccountTask *currentTask = authManager->getTaskFromManager(taskId);
107     if (currentTask == NULL) {
108         LOGE("Get task from manager failed, taskId: %d.", taskId);
109         return HC_ERR_TASK_ID_IS_NOT_MATCH;
110     }
111     LOGD("Begin process account related task, taskId: %d.", taskId);
112     return currentTask->processTask(currentTask, in, out, status);
113 }
114 
DestroyAccountTask(int taskId)115 static void DestroyAccountTask(int taskId)
116 {
117     if (HasAccountAuthPlugin() == HC_SUCCESS) {
118         (void)DestroyAuthSession(taskId);
119         return;
120     }
121     AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
122     if (authManager == NULL) {
123         LOGE("Get multi auth manager instance failed.");
124         return;
125     }
126     LOGI("Delete taskId:%d from task manager.", taskId);
127     authManager->deleteTaskFromManager(taskId);
128 }
129 
InitAccountModule(void)130 static int32_t InitAccountModule(void)
131 {
132     InitVersionInfos();
133     InitAccountMultiTaskManager();
134     return HC_SUCCESS;
135 }
136 
DestroyAccountModule(void)137 static void DestroyAccountModule(void)
138 {
139     DestroyAccountMultiTaskManager();
140     DestroyVersionInfos();
141 }
142 
143 static AccountModule g_module = {
144     .base.moduleType = ACCOUNT_MODULE,
145     .base.init = InitAccountModule,
146     .base.destroy = DestroyAccountModule,
147     .base.isMsgNeedIgnore = IsAccountMsgNeedIgnore,
148     .base.createTask = CreateAccountTask,
149     .base.processTask = ProcessAccountTask,
150     .base.destroyTask = DestroyAccountTask,
151 };
152 
GetAccountModule(void)153 const AuthModuleBase *GetAccountModule(void)
154 {
155     return (const AuthModuleBase *)&g_module;
156 }
157