• 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 "pake_v2_auth_client_task.h"
17 #include "common_defs.h"
18 #include "device_auth_defines.h"
19 #include "hc_types.h"
20 #include "hc_log.h"
21 #include "string_util.h"
22 #include "protocol_common.h"
23 #include "account_module.h"
24 #include "account_version_util.h"
25 #include "pake_v2_auth_task_common.h"
26 #include "pake_v2_protocol_common.h"
27 
28 enum {
29     TASK_STATUS_PAKE_MAIN_BEGIN = 0,
30     TASK_STATUS_PAKE_MAIN_STEP_ONE = 1,
31     TASK_STATUS_PAKE_MAIN_STEP_TWO = 2,
32     TASK_STATUS_PAKE_MAIN_END = 3,
33 };
34 
GetPakeV2AuthClientType(void)35 static AccountTaskType GetPakeV2AuthClientType(void)
36 {
37     return TASK_TYPE_PAKE_V2_AUTH_CLIENT;
38 }
39 
AsyAuthClientStepOne(TaskBase * task,const CJson * in,CJson * out,int32_t * status)40 static int32_t AsyAuthClientStepOne(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
41 {
42     PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
43     CJson *sendToPeer = CreateJson();
44     if (sendToPeer == NULL) {
45         LOGE("Failed to create sendToPeer json.");
46         return HC_ERR_JSON_CREATE;
47     }
48     CJson *data = CreateJson();
49     if (data == NULL) {
50         LOGE("Failed to create data json.");
51         FreeJson(sendToPeer);
52         return HC_ERR_JSON_CREATE;
53     }
54 
55     GOTO_IF_ERR(GetIntFromJson(in, FIELD_AUTH_FORM, &innerTask->params.authForm));
56     GOTO_IF_ERR(GetIntFromJson(in, FIELD_CREDENTIAL_TYPE, &innerTask->params.credentialType));
57 
58     GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, innerTask->params.authForm));
59     GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_USER_ID, (const char *)innerTask->params.userIdSelf));
60     GOTO_IF_ERR(AddIntToJson(sendToPeer, FIELD_STEP, CMD_PAKE_AUTH_MAIN_ONE));
61     GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_DEVICE_ID, (const char *)innerTask->params.deviceIdSelf.val));
62     GOTO_IF_ERR(AddStringToJson(sendToPeer, FIELD_DEV_ID, (const char *)innerTask->params.devIdSelf.val));
63 
64     GOTO_IF_ERR(AddIntToJson(data, FIELD_AUTH_KEY_ALG_ENCODE, ALG_ECC));
65     GOTO_IF_ERR(AddIntToJson(data, FIELD_CREDENTIAL_TYPE, innerTask->params.credentialType));
66     GOTO_IF_ERR(AddStringToJson(data, FIELD_AUTH_PK_INFO, (const char *)innerTask->params.pkInfoSelf.val));
67     GOTO_IF_ERR(AddByteToJson(data, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignSelf.val,
68         innerTask->params.pkInfoSignSelf.length));
69     GOTO_IF_ERR(AddObjToJson(sendToPeer, FIELD_DATA, data));
70     GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer));
71     innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_STEP_ONE;
72     *status = CONTINUE;
73     FreeJson(sendToPeer);
74     FreeJson(data);
75     return HC_SUCCESS;
76 ERR:
77     LOGE("Client step one failed.");
78     FreeJson(sendToPeer);
79     FreeJson(data);
80     return HC_ERR_AUTH_INTERNAL;
81 }
82 
DealAsyStepTwoData(PakeV2AuthClientTask * task)83 static int32_t DealAsyStepTwoData(PakeV2AuthClientTask *task)
84 {
85     if (ExtractPakeSelfId(&task->params) != HC_SUCCESS) {
86         LOGE("ExtractPakeSelfId failed for client.");
87         return HC_ERR_AUTH_INTERNAL;
88     }
89     if (VerifyPkSignPeer(&task->params) != HC_SUCCESS) {
90         LOGE("VerifyPkSignPeer failed for client.");
91         return HC_ERR_ACCOUNT_VERIFY_PK_SIGN;
92     }
93     if (GenerateEcdhSharedKey(&task->params) != HC_SUCCESS) {
94         LOGE("Generate ecdh shared key failed for client.");
95         return HC_ERR_ACCOUNT_ECDH_FAIL;
96     }
97     if (ClientConfirmPakeV2Protocol(&task->params.pakeParams)) {
98         LOGE("ClientConfirmPakeV2Protocol failed.");
99         return HC_ERR_CLIENT_CONFIRM_PROTOCOL;
100     }
101     return HC_SUCCESS;
102 }
103 
PrepareAsyClientStepTwoData(const PakeV2AuthClientTask * innerTask,CJson * out)104 static int32_t PrepareAsyClientStepTwoData(const PakeV2AuthClientTask *innerTask, CJson *out)
105 {
106     CJson *sendToPeer = CreateJson();
107     if (sendToPeer == NULL) {
108         LOGE("Create sendToPeer json NULL.");
109         return HC_ERR_JSON_CREATE;
110     }
111     CJson *data = CreateJson();
112     if (data == NULL) {
113         LOGE("Create data json NULL.");
114         FreeJson(sendToPeer);
115         return HC_ERR_JSON_CREATE;
116     }
117     int32_t ret = HC_SUCCESS;
118     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_AUTH_FORM, innerTask->params.authForm), ret);
119     GOTO_ERR_AND_SET_RET(AddIntToJson(sendToPeer, FIELD_STEP, CMD_PAKE_AUTH_MAIN_TWO), ret);
120     GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_KCF_DATA, innerTask->params.pakeParams.kcfData.val,
121         innerTask->params.pakeParams.kcfData.length), ret);
122     GOTO_ERR_AND_SET_RET(AddStringToJson(data, FIELD_DEVICE_ID,
123         (const char *)innerTask->params.deviceIdSelf.val), ret);
124     GOTO_ERR_AND_SET_RET(AddByteToJson(data, FIELD_EPK, innerTask->params.pakeParams.epkSelf.val,
125         innerTask->params.pakeParams.epkSelf.length), ret);
126     GOTO_ERR_AND_SET_RET(AddObjToJson(sendToPeer, FIELD_DATA, data), ret);
127     GOTO_ERR_AND_SET_RET(AddObjToJson(out, FIELD_SEND_TO_PEER, sendToPeer), ret);
128 ERR:
129     FreeJson(sendToPeer);
130     FreeJson(data);
131     return ret;
132 }
133 
AsyAuthClientStepTwo(TaskBase * task,const CJson * in,CJson * out,int32_t * status)134 static int32_t AsyAuthClientStepTwo(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
135 {
136     PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
137     if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_MAIN_STEP_ONE) {
138         LOGE("Client step two status error.");
139         return HC_ERR_AUTH_STATUS;
140     }
141     const char *userIdPeer = GetStringFromJson(in, FIELD_USER_ID);
142     uint32_t userIdPeerLen = HcStrlen(userIdPeer) + 1;
143     if (userIdPeer == NULL || userIdPeerLen > DEV_AUTH_USER_ID_SIZE) {
144         LOGE("Payload not contain peer userId or userId len is invalid.");
145         return HC_ERR_BAD_MESSAGE;
146     }
147     GOTO_IF_ERR(strcpy_s((char *)innerTask->params.userIdPeer, userIdPeerLen, userIdPeer));
148     GOTO_IF_ERR(GetPkInfoPeer(&innerTask->params, in));
149     GOTO_IF_ERR(ExtractPeerDeviceId(&innerTask->params, in));
150     GOTO_IF_ERR(ExtractPeerDevId(&innerTask->params, in));
151     GOTO_IF_ERR(ExtractPakePeerId(&innerTask->params, in));
152     GOTO_IF_ERR(GetByteFromJson(in, FIELD_AUTH_PK_INFO_SIGN, innerTask->params.pkInfoSignPeer.val,
153         innerTask->params.pkInfoSignPeer.length));
154     const char *pkInfoSignPeerStr = GetStringFromJson(in, FIELD_AUTH_PK_INFO_SIGN);
155     if (pkInfoSignPeerStr == NULL) {
156         LOGE("pkInfoSignPeer in client is null.");
157         return HC_ERR_NULL_PTR;
158     }
159     innerTask->params.pkInfoSignPeer.length = HcStrlen(pkInfoSignPeerStr) / BYTE_TO_HEX_OPER_LENGTH;
160     GOTO_IF_ERR(GetByteFromJson(in, FIELD_SALT, innerTask->params.pakeParams.salt.val,
161         innerTask->params.pakeParams.salt.length));
162     GOTO_IF_ERR(GetByteFromJson(in, FIELD_EPK, innerTask->params.pakeParams.epkPeer.val,
163         innerTask->params.pakeParams.epkPeer.length));
164 
165     GOTO_IF_ERR(DealAsyStepTwoData(innerTask));
166 
167     GOTO_IF_ERR(PrepareAsyClientStepTwoData(innerTask, out));
168 
169     innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_STEP_TWO;
170     *status = CONTINUE;
171     return HC_SUCCESS;
172 ERR:
173     LOGE("Client step two failed");
174     return HC_ERR_AUTH_INTERNAL;
175 }
176 
DealAsyStepThreeData(PakeAuthParams * params)177 static int32_t DealAsyStepThreeData(PakeAuthParams *params)
178 {
179     int32_t res = ClientVerifyConfirmPakeV2Protocol(&params->pakeParams);
180     if (res != HC_SUCCESS) {
181         LOGE("Client Verify ConfirmPakeV2Protocol failed.");
182     }
183     return res;
184 }
185 
SendFinalToOut(PakeV2AuthClientTask * task,CJson * out)186 static int32_t SendFinalToOut(PakeV2AuthClientTask *task, CJson *out)
187 {
188     CJson *sendToSelf = CreateJson();
189     if (sendToSelf == NULL) {
190         LOGE("Create sendToSelf json NULL.");
191         return HC_ERR_JSON_CREATE;
192     }
193     GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_USER_ID, (const char *)task->params.userIdPeer));
194     GOTO_IF_ERR(AddByteToJson(sendToSelf,
195         FIELD_SESSION_KEY, task->params.pakeParams.sessionKey.val, task->params.pakeParams.sessionKey.length));
196     GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEVICE_ID, (const char *)task->params.deviceIdSelf.val));
197     GOTO_IF_ERR(AddStringToJson(sendToSelf, FIELD_DEV_ID, (const char *)task->params.devIdPeer.val));
198     GOTO_IF_ERR(AddIntToJson(sendToSelf, FIELD_CREDENTIAL_TYPE, ASYMMETRIC_CRED));
199 
200     GOTO_IF_ERR(AddObjToJson(out, FIELD_SEND_TO_SELF, sendToSelf));
201     FreeJson(sendToSelf);
202     FreeAndCleanKey(&task->params.pakeParams.sessionKey);
203     return HC_SUCCESS;
204 ERR:
205     FreeAndCleanKey(&task->params.pakeParams.sessionKey);
206     FreeJson(sendToSelf);
207     LOGE("SendFinalToOut failed");
208     return HC_ERR_AUTH_INTERNAL;
209 }
210 
AsyAuthClientStepThree(TaskBase * task,const CJson * in,CJson * out,int32_t * status)211 static int32_t AsyAuthClientStepThree(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
212 {
213     PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
214     if (innerTask->taskBase.taskStatus != TASK_STATUS_PAKE_MAIN_STEP_TWO) {
215         LOGE("Client step three status error.");
216         return HC_ERR_AUTH_STATUS;
217     }
218     GOTO_IF_ERR(GetByteFromJson(in, FIELD_KCF_DATA,
219         innerTask->params.pakeParams.kcfDataPeer.val, innerTask->params.pakeParams.kcfDataPeer.length));
220     GOTO_IF_ERR(DealAsyStepThreeData(&innerTask->params));
221     GOTO_IF_ERR(SendFinalToOut(innerTask, out));
222     innerTask->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_END;
223     *status = FINISH;
224     return HC_SUCCESS;
225 ERR:
226     LOGE("Client step three failed");
227     return HC_ERR_AUTH_INTERNAL;
228 }
229 
ProcessClientTask(TaskBase * task,const CJson * in,CJson * out,int32_t * status)230 static int32_t ProcessClientTask(TaskBase *task, const CJson *in, CJson *out, int32_t *status)
231 {
232     LOGI("Start process client pake v2 auth task.");
233     if (task == NULL || in == NULL || out == NULL || status == NULL) {
234         LOGE("ProcessClientTask in params NULL.");
235         return HC_ERR_INVALID_PARAMS;
236     }
237 
238     if (task->taskStatus == TASK_STATUS_PAKE_MAIN_BEGIN) {
239         return AsyAuthClientStepOne(task, in, out, status);
240     }
241     int32_t step = 0; // step comes from opposite device
242     if (GetIntFromJson(in, FIELD_STEP, &step) != HC_SUCCESS) {
243         LOGE("Get no auth step.");
244         return HC_ERR_JSON_GET;
245     }
246     int32_t res;
247     switch (step) {
248         case RET_PAKE_AUTH_FOLLOWER_ONE: // the step name of the opposite
249             res = AsyAuthClientStepTwo(task, in, out, status);
250             break;
251         case RET_PAKE_AUTH_FOLLOWER_TWO:
252             res = AsyAuthClientStepThree(task, in, out, status);
253             break;
254         case ERR_MSG:
255             return HC_ERR_PEER_ERROR;
256         default:
257             res = HC_ERR_BAD_MESSAGE;
258             break;
259     }
260     if (res != HC_SUCCESS) {
261         LOGE("error occurred and send error");
262         return res;
263     }
264     LOGI("End process client, step = %d", step);
265     return HC_SUCCESS;
266 }
267 
DestroyAuthClientAuthTask(TaskBase * task)268 static void DestroyAuthClientAuthTask(TaskBase *task)
269 {
270     if (task == NULL) {
271         LOGD("Task is NULL");
272         return;
273     }
274     PakeV2AuthClientTask *innerTask = (PakeV2AuthClientTask *)task;
275     DestroyPakeAuthParams(&(innerTask->params));
276     HcFree(innerTask);
277 }
278 
CreatePakeV2AuthClientTask(const CJson * in,CJson * out,const AccountVersionInfo * verInfo)279 TaskBase *CreatePakeV2AuthClientTask(const CJson *in, CJson *out, const AccountVersionInfo *verInfo)
280 {
281     if (in == NULL || out == NULL || verInfo == NULL) {
282         LOGE("Params is null for create client pake v2 auth task.");
283         return NULL;
284     }
285     PakeV2AuthClientTask *taskParams = (PakeV2AuthClientTask *)HcMalloc(sizeof(PakeV2AuthClientTask), 0);
286     if (taskParams == NULL) {
287         LOGE("Malloc for PakeV2AuthClientTask failed.");
288         return NULL;
289     }
290     taskParams->taskBase.getTaskType = GetPakeV2AuthClientType;
291     taskParams->taskBase.destroyTask = DestroyAuthClientAuthTask;
292     taskParams->taskBase.process = ProcessClientTask;
293     int32_t res = InitPakeAuthParams(in, &(taskParams->params), verInfo);
294     if (res != HC_SUCCESS) {
295         DestroyAuthClientAuthTask((TaskBase *)taskParams);
296         LOGE("InitPakeAuthParams failed");
297         return NULL;
298     }
299 
300     taskParams->taskBase.taskStatus = TASK_STATUS_PAKE_MAIN_BEGIN;
301     return (TaskBase *)taskParams;
302 }