• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_task_main.h"
17 #include "alg_defs.h"
18 #include "alg_loader.h"
19 #include "common_defs.h"
20 #include "device_auth.h"
21 #include "device_auth_defines.h"
22 #include "clib_error.h"
23 #include "hc_log.h"
24 #include "json_utils.h"
25 #include "account_version_util.h"
26 
AccountSendErrMsgToSelf(CJson * out,int32_t errCode)27 static void AccountSendErrMsgToSelf(CJson *out, int32_t errCode)
28 {
29     CJson *sendToSelf = CreateJson();
30     if (sendToSelf == NULL) {
31         LOGE("Create sendToSelf json failed.");
32         return;
33     }
34     if (AddIntToJson(sendToSelf, FIELD_ERROR_CODE, errCode) != CLIB_SUCCESS) {
35         LOGE("Add errCode to self json failed.");
36         FreeJson(sendToSelf);
37         return;
38     }
39     if (AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf) != CLIB_SUCCESS) {
40         LOGE("Add sendToSelf obj to out json failed.");
41         FreeJson(sendToSelf);
42         return;
43     }
44     FreeJson(sendToSelf);
45 }
46 
AccountSendErrMsgToOut(CJson * out,int32_t opCode,int32_t errCode)47 static void AccountSendErrMsgToOut(CJson *out, int32_t opCode, int32_t errCode)
48 {
49     CJson *sendToSelf = CreateJson();
50     if (sendToSelf == NULL) {
51         LOGE("Create sendToSelf json failed.");
52         return;
53     }
54     CJson *sendToPeer = CreateJson();
55     if (sendToPeer == NULL) {
56         LOGE("Create sendToPeer json failed.");
57         FreeJson(sendToSelf);
58         return;
59     }
60     if (opCode == OP_BIND) {
61         if (AddIntToJson(sendToPeer, FIELD_MESSAGE, ERR_MSG) != CLIB_SUCCESS) {
62             LOGE("Failed to add error message to json for bind.");
63             goto CLEAN_UP;
64         }
65     } else {
66         if (AddIntToJson(sendToPeer, FIELD_STEP, ERR_MSG) != CLIB_SUCCESS) {
67             LOGE("Failed to add error message to json for auth.");
68             goto CLEAN_UP;
69         }
70     }
71     if (AddIntToJson(sendToPeer, FIELD_ERROR_CODE, errCode) != CLIB_SUCCESS) {
72         LOGE("Add errCode to json failed.");
73         goto CLEAN_UP;
74     }
75     if (AddIntToJson(sendToSelf, FIELD_AUTH_FORM, ACCOUNT_MODULE) != CLIB_SUCCESS) {
76         LOGE("Add auth form to json failed.");
77         goto CLEAN_UP;
78     }
79     if (AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer) != CLIB_SUCCESS) {
80         LOGE("Add sendToPeer to json failed.");
81         goto CLEAN_UP;
82     }
83     if (AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf) != CLIB_SUCCESS) {
84         LOGE("Add sendToSelf to json failed.");
85         goto CLEAN_UP;
86     }
87 
88 CLEAN_UP:
89     FreeJson(sendToPeer);
90     FreeJson(sendToSelf);
91     return;
92 }
93 
DestroyTaskT(AccountTask * task)94 static void DestroyTaskT(AccountTask *task)
95 {
96     if (task == NULL) {
97         return;
98     }
99     if (task->subTask != NULL) {
100         task->subTask->destroyTask(task->subTask);
101     }
102     HcFree(task);
103 }
104 
IsPeerErrMessage(const CJson * in)105 static bool IsPeerErrMessage(const CJson *in)
106 {
107     int32_t res = 0;
108     int32_t message = 0;
109     if ((GetIntFromJson(in, FIELD_MESSAGE, &message) != CLIB_SUCCESS) &&
110         (GetIntFromJson(in, FIELD_STEP, &message) != CLIB_SUCCESS)) {
111         LOGD("There is no message code."); // The first message of the client has no message code
112         return false;
113     }
114     if (message != ERR_MSG) {
115         return false;
116     }
117 
118     if (GetIntFromJson(in, FIELD_ERROR_CODE, &res) != CLIB_SUCCESS) {
119         LOGE("Get peer error code failed.");
120     }
121     LOGE("Receive error message from peer, errCode: %x.", res);
122     return true;
123 }
124 
MapSubTaskTypeToOpCode(AccountTaskType subTaskType)125 static int32_t MapSubTaskTypeToOpCode(AccountTaskType subTaskType)
126 {
127     if (subTaskType >= TASK_TYPE_PAKE_V2_AUTH_CLIENT && subTaskType <= TASK_TYPE_ISO_AUTH_SERVER) {
128         return AUTHENTICATE;
129     }
130     return CODE_NULL;
131 }
132 
ProcessTaskT(AccountTask * task,const CJson * in,CJson * out,int32_t * status)133 static int32_t ProcessTaskT(AccountTask *task, const CJson *in, CJson *out, int32_t *status)
134 {
135     if (IsPeerErrMessage(in)) {
136         AccountSendErrMsgToSelf(out, HC_ERR_PEER_ERROR);
137         return HC_ERR_PEER_ERROR;
138     }
139     int32_t res = task->subTask->process(task->subTask, in, out, status);
140     if (res != HC_SUCCESS) {
141         LOGE("Process subTask failed, res: %x.", res);
142         int32_t operationCode = MapSubTaskTypeToOpCode(task->subTask->getTaskType());
143         AccountSendErrMsgToOut(out, operationCode, res);
144     }
145     return res;
146 }
147 
NegotiateAndCreateSubTask(AccountTask * task,const CJson * in,CJson * out)148 static int32_t NegotiateAndCreateSubTask(AccountTask *task, const CJson *in, CJson *out)
149 {
150     int32_t operationCode = 0;
151     int32_t credentialType = INVALID_CRED;
152     if (GetIntFromJson(in, FIELD_OPERATION_CODE, &operationCode) != CLIB_SUCCESS) {
153         LOGE("Get operationCode from json failed.");
154         return HC_ERR_JSON_GET;
155     }
156     if (GetIntFromJson(in, FIELD_CREDENTIAL_TYPE, &credentialType) != CLIB_SUCCESS) {
157         LOGE("Failed to get credential type from input data.");
158         return HC_ERR_JSON_GET;
159     }
160     const AccountVersionInfo *verInfo = GetNegotiatedVersionInfo(operationCode, credentialType);
161     if (verInfo == NULL) {
162         LOGE("Get Negotiated versionInfo failed.");
163         return HC_ERR_UNSUPPORTED_VERSION;
164     }
165     task->subTask = verInfo->createTask(in, out, verInfo);
166     if (task->subTask == NULL) {
167         LOGE("Create sub task failed.");
168         return HC_ERR_ALLOC_MEMORY;
169     }
170     task->versionStatus = VERSION_CONFIRMED;
171     return HC_SUCCESS;
172 }
173 
AccountSendCreateError(const CJson * in,CJson * out,int32_t errCode)174 static void AccountSendCreateError(const CJson *in, CJson *out, int32_t errCode)
175 {
176     bool isClient = false;
177     if (GetBoolFromJson(in, FIELD_IS_CLIENT, &isClient) != CLIB_SUCCESS) {
178         LOGE("Get isClient from json failed.");
179     }
180     if (isClient) {
181         AccountSendErrMsgToSelf(out, errCode);
182         return;
183     }
184     int32_t operationCode = CODE_NULL;
185     if (GetIntFromJson(in, FIELD_OPERATION_CODE, &operationCode) != CLIB_SUCCESS) {
186         LOGE("Get operationCode from json failed.");
187     } else {
188         AccountSendErrMsgToOut(out, operationCode, errCode);
189     }
190 }
191 
CreateAccountTaskT(int32_t * taskId,const CJson * in,CJson * out)192 AccountTask *CreateAccountTaskT(int32_t *taskId, const CJson *in, CJson *out)
193 {
194     int32_t res;
195     AccountTask *task = (AccountTask *)HcMalloc(sizeof(AccountTask), 0);
196     if (task == NULL) {
197         LOGE("Malloc for account related task failed.");
198         res = HC_ERR_ALLOC_MEMORY;
199         goto ERR;
200     }
201     task->destroyTask = DestroyTaskT;
202     task->processTask = ProcessTaskT;
203     task->versionStatus = VERSION_INITIAL;
204     Uint8Buff taskIdBuf = { (uint8_t *)taskId, sizeof(int32_t) };
205     res = GetLoaderInstance()->generateRandom(&taskIdBuf);
206     if (res != HC_SUCCESS) {
207         LOGE("Generate taskId failed, res: %d.", res);
208         goto ERR;
209     }
210     task->taskId = *taskId;
211     res = NegotiateAndCreateSubTask(task, in, out);
212     if (res != HC_SUCCESS) {
213         LOGE("NegotiateAndCreateSubTask failed, res: %d.", res);
214         goto ERR;
215     }
216     return task;
217 ERR:
218     AccountSendCreateError(in, out, res);
219     DestroyTaskT(task);
220     return NULL;
221 }
222