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 "account_module.h"
17 #include "account_module_defines.h"
18 #include "account_multi_task_manager.h"
19 #include "account_version_util.h"
20 #include "alg_loader.h"
21 #include "asy_token_manager.h"
22 #include "clib_error.h"
23 #include "clib_types.h"
24 #include "common_defs.h"
25 #include "device_auth_defines.h"
26 #include "hc_log.h"
27 #include "json_utils.h"
28 #include "pake_v2_auth_client_task.h"
29 #include "pake_v2_auth_server_task.h"
30 #include "sym_token_manager.h"
31
32 #define ACCOUNT_CLIENT_FIRST_MESSAGE 0x0000
33 #define ACCOUNT_CLIENT_STEP_MASK 0x000F
34
35 typedef struct {
36 AuthModuleBase moduleBase;
37 } AccountModule;
38
39 static AccountModule g_module;
40
CheckAccountMsgRepeatability(const CJson * in)41 int32_t CheckAccountMsgRepeatability(const CJson *in)
42 {
43 int32_t opCode;
44 if (GetIntFromJson(in, FIELD_OPERATION_CODE, &opCode) != CLIB_SUCCESS) {
45 LOGE("Get opCode failed.");
46 return HC_ERR_JSON_GET;
47 }
48 const char *key = NULL;
49 if (opCode == OP_BIND) {
50 key = FIELD_MESSAGE;
51 } else if (opCode == AUTHENTICATE) {
52 key = FIELD_STEP;
53 } else {
54 LOGE("Invalid opCode: %d.", opCode);
55 return HC_ERR_INVALID_PARAMS;
56 }
57 uint32_t message;
58 if (GetIntFromJson(in, key, (int32_t *)&message) != CLIB_SUCCESS) {
59 LOGD("There is no message code."); // The first message of the client has no message code
60 return HC_SUCCESS;
61 }
62 if ((message & ACCOUNT_CLIENT_STEP_MASK) == ACCOUNT_CLIENT_FIRST_MESSAGE) {
63 return HC_SUCCESS;
64 }
65
66 LOGI("The message is repeated, ignore it, code: %u", message);
67 return HC_ERR_IGNORE_MSG;
68 }
69
CreateAccountTask(int32_t * taskId,const CJson * in,CJson * out)70 static int32_t CreateAccountTask(int32_t *taskId, const CJson *in, CJson *out)
71 {
72 if (taskId == NULL || in == NULL || out == NULL) {
73 LOGE("Params is null in account task.");
74 return HC_ERR_NULL_PTR;
75 }
76 int32_t res = CheckAccountMsgRepeatability(in);
77 if (res != HC_SUCCESS) {
78 LOGE("The result of CheckAccountMsgRepeatability is %x.", res);
79 return res;
80 }
81 AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
82 if (authManager == NULL) {
83 LOGE("Get multi auth manager instance failed.");
84 return HC_ERROR;
85 }
86 if (authManager->isTaskNumUpToMax() == true) {
87 LOGE("Account auth task is full.");
88 return HC_ERR_ACCOUNT_TASK_IS_FULL;
89 }
90 AccountTask *newTask = CreateAccountTaskT(taskId, in, out);
91 if (newTask == NULL) {
92 LOGE("Create account related task failed.");
93 return HC_ERR_ALLOC_MEMORY;
94 }
95 res = authManager->addTaskToManager(newTask);
96 if (res != HC_SUCCESS) {
97 LOGE("Add new task into task manager failed, res: %d.", res);
98 newTask->destroyTask(newTask);
99 }
100 return res;
101 }
102
ProcessAccountTask(int32_t taskId,const CJson * in,CJson * out,int32_t * status)103 static int32_t ProcessAccountTask(int32_t taskId, const CJson *in, CJson *out, int32_t *status)
104 {
105 AccountMultiTaskManager *authManager = GetAccountMultiTaskManager();
106 if (authManager == NULL) {
107 LOGE("Get multi auth manager instance failed.");
108 return HC_ERROR;
109 }
110 AccountTask *currentTask = authManager->getTaskFromManager(taskId);
111 if (currentTask == NULL) {
112 LOGE("Get task from manager failed, taskId: %d.", taskId);
113 return HC_ERR_TASK_ID_IS_NOT_MATCH;
114 }
115 LOGD("Begin process account related task, taskId: %d.", taskId);
116 return currentTask->processTask(currentTask, in, out, status);
117 }
118
DestroyAccountTask(int32_t taskId)119 static void DestroyAccountTask(int32_t taskId)
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
ProcessAsyTokens(int32_t osAccountId,int32_t opCode,CJson * in,CJson * out)130 static int32_t ProcessAsyTokens(int32_t osAccountId, int32_t opCode, CJson *in, CJson *out)
131 {
132 switch (opCode) {
133 case IMPORT_SELF_CREDENTIAL:
134 case IMPORT_TRUSTED_CREDENTIALS:
135 return GetAccountAuthTokenManager()->addToken(osAccountId, opCode, in);
136 case DELETE_SELF_CREDENTIAL:
137 case DELETE_TRUSTED_CREDENTIALS: {
138 const char *userId = GetStringFromJson(in, FIELD_USER_ID);
139 if (userId == NULL) {
140 LOGE("Failed to get user id.");
141 return HC_ERR_JSON_GET;
142 }
143 const char *deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
144 if (deviceId == NULL) {
145 LOGE("Failed to get deviceId from json!");
146 return HC_ERR_JSON_GET;
147 }
148 return GetAccountAuthTokenManager()->deleteToken(osAccountId, userId, deviceId);
149 }
150 case REQUEST_SIGNATURE:
151 if (out == NULL) {
152 LOGE("Params: out is null.");
153 return HC_ERR_NULL_PTR;
154 }
155 return GetAccountAuthTokenManager()->getRegisterProof(in, out);
156 default:
157 LOGE("Operation is not supported for: %d.", opCode);
158 return HC_ERR_NOT_SUPPORT;
159 }
160 }
161
ProcessSymTokens(int32_t osAccountId,int32_t opCode,CJson * in,CJson * out)162 static int32_t ProcessSymTokens(int32_t osAccountId, int32_t opCode, CJson *in, CJson *out)
163 {
164 switch (opCode) {
165 case IMPORT_SELF_CREDENTIAL:
166 case IMPORT_TRUSTED_CREDENTIALS:
167 return GetSymTokenManager()->addToken(osAccountId, opCode, in);
168 case DELETE_SELF_CREDENTIAL:
169 case DELETE_TRUSTED_CREDENTIALS: {
170 const char *userId = GetStringFromJson(in, FIELD_USER_ID);
171 if (userId == NULL) {
172 LOGE("Failed to get userId from json!");
173 return HC_ERR_JSON_GET;
174 }
175 const char *deviceId = GetStringFromJson(in, FIELD_DEVICE_ID);
176 if (deviceId == NULL) {
177 LOGE("Failed to get deviceId from json!");
178 return HC_ERR_JSON_GET;
179 }
180 return GetSymTokenManager()->deleteToken(osAccountId, userId, deviceId);
181 }
182 default:
183 LOGE("Operation is not supported for: %d.", opCode);
184 return HC_ERR_NOT_SUPPORT;
185 }
186 }
187
DestroyAccountModule(AuthModuleBase * module)188 static void DestroyAccountModule(AuthModuleBase *module)
189 {
190 DestroyAccountMultiTaskManager();
191 DestroyTokenManager();
192 DestroySymTokenManager();
193 DestroyVersionInfos();
194 (void)memset_s(module, sizeof(AccountModule), 0, sizeof(AccountModule));
195 }
196
CreateAccountModule(void)197 AuthModuleBase *CreateAccountModule(void)
198 {
199 g_module.moduleBase.moduleType = ACCOUNT_MODULE;
200 g_module.moduleBase.createTask = CreateAccountTask;
201 g_module.moduleBase.processTask = ProcessAccountTask;
202 g_module.moduleBase.destroyTask = DestroyAccountTask;
203 g_module.moduleBase.destroyModule = DestroyAccountModule;
204
205 InitVersionInfos();
206 InitAccountMultiTaskManager();
207 InitTokenManager();
208 InitSymTokenManager();
209 return (AuthModuleBase *)&g_module;
210 }
211
IsAccountSupported(void)212 bool IsAccountSupported(void)
213 {
214 return true;
215 }
216
ProcessAccountCredentials(int32_t osAccountId,int32_t opCode,CJson * in,CJson * out)217 int32_t ProcessAccountCredentials(int32_t osAccountId, int32_t opCode, CJson *in, CJson *out)
218 {
219 if (in == NULL) {
220 LOGE("The input param: in is null.");
221 return HC_ERR_NULL_PTR;
222 }
223 int32_t credentialType = INVALID_CRED;
224 if (GetIntFromJson(in, FIELD_CREDENTIAL_TYPE, &credentialType) != HC_SUCCESS) {
225 LOGE("Failed to get credentialType from json!");
226 return HC_ERR_JSON_GET;
227 }
228 if (credentialType == ASYMMETRIC_CRED) {
229 return ProcessAsyTokens(osAccountId, opCode, in, out);
230 } else if (credentialType == SYMMETRIC_CRED) {
231 return ProcessSymTokens(osAccountId, opCode, in, out);
232 } else {
233 LOGE("Invalid credential type! [CredType]: %d", credentialType);
234 return HC_ERR_NOT_SUPPORT;
235 }
236 }
237